Repository navigation
chore(core/docs): changelog automation, ref alignment, constants unification, safety sweeps - #169
Conversation
…ardening(cache): replace strcpy ZERO oid with gm_snprintf
…ants to include/gitmind/cbor; remove duplicate constants.h; set GM_PATH_MAX=4096; add gm_build_ref and align edges ref prefix
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (1)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including You can disable this status message by setting the WalkthroughReplaces the git-lfs pre-push hook with a Bash hook enforcing CHANGELOG and worksheet checks (HOOKS_BYPASS), introduces gm_build_ref and ref validation, migrates internals to OID-first and safer gm_* memory/string utilities, annotates results with GM_NODISCARD, maps legacy GM_* error macros to GM_ERR_*, adds tests and review‑seeding/worksheet tooling, and performs a large docs/front‑matter and CI/tooling sweep. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Dev as Developer
participant Git as Git client
participant Hook as pre-push hook
Note over Hook: pre-push enforces main CHANGELOG + worksheet checks
Dev->>Git: git push <remote> <refspec>
Git->>Hook: invoke pre-push (args + stdin refs)
Hook->>Hook: if HOOKS_BYPASS=1 -> exit 0
Hook->>Hook: parse args, read ref-updates
Hook->>Hook: for each ref -> if ref != refs/heads/main -> skip
Hook->>Hook: compute range (remote..local or local^..local)
Hook->>Git: git diff --name-only <range>
alt CHANGELOG present
Hook-->>Dev: exit 0
else
Hook-->>Dev: stderr guidance + suggested make/HOOKS_BYPASS, exit 1
end
sequenceDiagram
autonumber
participant Ctx as gm_context_t
participant Cache as gm_cache_load_meta
participant Util as gm_build_ref
participant Git as libgit2
Note over Cache: OID-first cache ref resolution with legacy fallback
Ctx->>Cache: gm_cache_load_meta(branch)
Cache->>Util: gm_build_ref(out, sz, GITMIND_EDGES_REF_PREFIX, branch)
alt build ok
Cache->>Git: resolve ref -> oid
alt oid found
Cache->>Cache: populate journal_tip_oid_bin + journal_tip_oid
else legacy path
Cache->>Git: find legacy ref -> populate meta from legacy ref
end
else
Cache-->>Ctx: return error
end
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 28
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (17)
core/include/gitmind/types.h (1)
23-27: Avoid fallback defining GIT_OID_RAWSZ; enforce compile-time check to prevent mismatches.Silently defaulting to 20 risks ABI/size mismatches if libgit2 is built with SHA‑256 (32). Gate on libgit2’s define and assert allowed sizes.
-#ifndef GIT_OID_RAWSZ -#define GIT_OID_RAWSZ 20 -#endif -#define GM_OID_RAWSZ GIT_OID_RAWSZ +#if !defined(GIT_OID_RAWSZ) +# error "libgit2 must define GIT_OID_RAWSZ; include <git2/oid.h> before this header." +#endif +#if (GIT_OID_RAWSZ != 20) && (GIT_OID_RAWSZ != 32) +# error "Unsupported GIT_OID_RAWSZ; expected 20 (SHA-1) or 32 (SHA-256)." +#endif +#define GM_OID_RAWSZ GIT_OID_RAWSZdocs/quality/local-ci-parity.md (1)
42-46: Remove duplicated bullets in Notes.
The two bullets about clang-tidy exclusion and PR validation are repeated.- - CI clang‑tidy excludes `core/src/hooks/`; local scripts mirror that. - - For PRs, validate locally first, then push and check GitHub checks with `gh pr view`.docs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_angle-includes.md (1)
17-17: Fix doubled bullet prefix (“- - …”).Use a single “- ” for the list item.
- - We keep project headers included with quotes for consistency across CLI sources. Switching this single header to angle brackets would introduce inconsistency without functional benefit. + - We keep project headers included with quotes for consistency across CLI sources. Switching this single header to angle brackets would introduce inconsistency without functional benefit.docs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_e2e-refactor.md (1)
17-17: Fix doubled bullet prefix (“- - …”).Use a single “- ” for the list item.
- - The current script already honors GIT_MIND and common build locations. Larger refactors (e.g., richer reporting or temp dirs) will be addressed alongside test coverage changes. + - The current script already honors GIT_MIND and common build locations. Larger refactors (e.g., richer reporting or temp dirs) will be addressed alongside test coverage changes.docs/audits/vision-drift.md (1)
101-101: Replace placeholder “Last reviewed: ” with an actual date or derive from front matter.Either render from
last_updatedor set a concrete ISO date.-Last reviewed: <set-on-commit> +Last reviewed: 2025-09-15core/src/cache/tree_builder.c (1)
68-75: Consistent handling of path-too-long cases.process_fs_entry returns GM_ERR_BUFFER_TOO_SMALL on overflow; elsewhere lstat failures are skipped (GM_OK). Confirm this strict failure is intentional; if not, consider skipping with a warning for resilience.
docs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_umbrella-safety-include.md (1)
17-17: Fix accidental double list marker (“- - …”).Removes markdownlint noise and renders as a single bullet.
-- - Safety utilities are CLI‑only and not part of the core public API we want consumers to depend on. Keeping them out of the umbrella avoids accidental external coupling. +- Safety utilities are CLI‑only and not part of the core public API we want consumers to depend on. Keeping them out of the umbrella avoids accidental external coupling.docs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_markdownlint.md (1)
17-17: Fix accidental double list marker (“- - …”).Aligns with markdownlint expectations for lists.
-- - The project does not enforce markdownlint in CI; current README renders well and existing docs checks (links/TOC) pass. We'll adopt markdownlint rules repo‑wide in a docs sweep rather than piecemeal edits here. +- The project does not enforce markdownlint in CI; current README renders well and existing docs checks (links/TOC) pass. We'll adopt markdownlint rules repo‑wide in a docs sweep rather than piecemeal edits here.docs/architecture/deprecations/legacy-sha-fields.md (1)
44-49: Review the migration timeline and grace period.The migration plan mentions "After one minor release" but doesn't specify clear version targets or timeline. Consider adding specific version numbers or dates for the deprecation phases.
-3. After one minor release, remove `src_sha`/`tgt_sha` from public structs and drop legacy CBOR keys from writers (readers may retain legacy acceptance for another cycle if needed). +3. Target for v0.3.0: remove `src_sha`/`tgt_sha` from public structs and drop legacy CBOR keys from writers (readers may retain legacy acceptance through v0.4.0 if needed).docs/enforcer/reviews/2025-06-22-review.md (2)
60-67: Review the union-based error message suggestion.The proposed union structure for error messages seems unnecessarily complex for most use cases. Consider whether this optimization is needed or if a simpler approach would suffice.
-union { char small[48]; char *heap; } msg; -uint16_t len; -bool heap_alloc; +char *msg; // Always heap allocated +size_t len; +size_t capacity;This simpler approach avoids the complexity of managing small string optimization while still preventing truncation.
94-96: Shell pattern could be more robust.The grep pattern for checking TODOs might miss some variations and could be refined.
-grep -nE "(TODO|FIXME|XXX)" $(git ls-files '*.c' '*.h') && \ +rg -nE '\b(TODO|FIXME|XXX|HACK|BUG)\b' --type=c --type=h && \Using
rgwith word boundaries is more precise and faster thangrep.docs/enforcer/gameplans/02-memory-architecture-revolution.md (1)
158-162: Consider safer RAII macro pattern.The
GM_WITH_ARENAmacro could have issues with nested usage or early returns. Consider a more robust implementation.-#define GM_WITH_ARENA(arena, size, name) \ - for (gm_arena_t *arena = gm_arena_create(size, name); \ - arena; \ - gm_arena_destroy(arena), arena = NULL) +#define GM_WITH_ARENA(arena, size, name) \ + for (gm_arena_t *arena = gm_arena_create(size, name), *_cleanup = arena; \ + arena; \ + gm_arena_destroy(_cleanup), arena = NULL)This prevents issues if
arenais modified within the loop body.docs/architecture/tombstone-visual.md (1)
11-208: Action: reconcile tombstone docs with implementationDocumentation states tombstones are edges with negative confidence, but the code enforces confidence in 0.0–1.0 (see include/gitmind/constants.h — GM_ERR_INVALID_CONF) and attribution filters use float min_confidence/max_confidence (include/gitmind/attribution.h). No tombstone/negative-confidence usage found. Either update the docs to describe the actual tombstone encoding (e.g., a flag/tag) or modify validation/filtering to support negative-confidence tombstones and add tests.
core/src/journal/reader.c (1)
33-33: Remove obsolete constant definition.The
REFS_GITMIND_PREFIXconstant on Line 33 is no longer used since the code now usesGITMIND_EDGES_REF_PREFIXviagm_build_ref. This should be removed to avoid confusion.-#define REFS_GITMIND_PREFIX "refs/gitmind/edges/"docs/specs/Technical_Specifications.md (3)
40-57: API contracts: document gm_build_ref and ref-prefix constant to match PR objectives.Specs mention deterministic, safe ref construction elsewhere in the PR. Add the ref builder and error semantics here.
## API Contracts Library (C): ```c // Normalize UTF-8 to NFC; returns length written (0 on error) size_t gm_utf8_nfc(char* dst, size_t dst_size, const char* src); // Deterministic 64-bit IDs for semantics uint64_t gm_sem_type_id(const char* type_name_utf8); uint64_t gm_sem_lane_id(const char* lane_name_utf8); +// Build a fully-qualified ref name safely: out <- prefix + branch +// Returns 0 on success; negative error codes on failure (e.g., GM_ERR_BUFFER_TOO_SMALL, GM_ERR_INVALID_BRANCH) +int gm_build_ref(char* out, size_t out_sz, const char* prefix, const char* branch); + // Append attributed edge (names-as-truth) int gm_edge_append(const gm_edge_attributed_t* edge); // List edges with filters by names; output iterator-based int gm_list(const gm_list_filter_t* filter, gm_edge_iter_t* out_iter);Please confirm exact signature and error codes, then update. --- `25-39`: **Surface constants used by the new flows.** Call out buffer/path max and ref prefix to keep consumers aligned. ```diff ## Implementation Approach @@ - Advice - Minimal schema; merge via hybrid CRDT with LWW scalars and OR-Set collections - Application limited to `symmetric` and `implies` initially + +### Constants +- `GM_PATH_MAX = 4096` (normalized; governs ref/path buffers) +- `GITMIND_EDGES_REF_PREFIX = "refs/gitmind/edges/"` (reserved namespace for cache/journal artifacts)
71-76: Add language identifiers to fenced blocks (MD040).Use “text” for CBOR shapes to satisfy markdownlint.
-``` +```text [ src_sha(20), tgt_sha(20), confidence(u16-half), timestamp(u64), src_path(tstr), tgt_path(tstr), ulid(tstr), type_name(tstr), lane_name(tstr), attribution(map) ]-
+text
{ kind: tstr, subject: tstr, props: map, ulid: tstr, ts: u64, actor: tstr }Also applies to: 79-81
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (107)
.githooks/pre-push(1 hunks).pre-commit-config.yaml(1 hunks)Makefile(1 hunks)core/include/gitmind/constants.h(0 hunks)core/include/gitmind/types.h(1 hunks)core/include/gitmind/util/ref.h(1 hunks)core/src/cache/builder.c(1 hunks)core/src/cache/query.c(1 hunks)core/src/cache/tree_builder.c(1 hunks)core/src/journal/reader.c(2 hunks)core/src/journal/writer.c(2 hunks)core/src/util/ref.c(1 hunks)docs/CI_STRATEGY.md(1 hunks)docs/DEV_SETUP.md(2 hunks)docs/Legacy_Mapping.md(1 hunks)docs/PRDs/PRD-co-thought-mcp-service.md(1 hunks)docs/PRDs/PRD-git-mind-semantics-time-travel-prototype.md(1 hunks)docs/README.md(2 hunks)docs/adr/0001-first-class-semantics.md(1 hunks)docs/adr/0002-docs-reorganization.md(1 hunks)docs/adult_swim.md(1 hunks)docs/api/gitmind-api-reference.md(1 hunks)docs/architecture/MIGRATION_PHILOSOPHY.md(1 hunks)docs/architecture/MODULAR_RESTRUCTURE_PLAN.md(1 hunks)docs/architecture/README.md(1 hunks)docs/architecture/System_Architecture.md(1 hunks)docs/architecture/attribution-integration-guide.md(1 hunks)docs/architecture/attribution-system.md(1 hunks)docs/architecture/attribution-use-cases.md(1 hunks)docs/architecture/augments-system.md(1 hunks)docs/architecture/bitmap-cache-design.md(1 hunks)docs/architecture/cache-migration-oid-only.md(1 hunks)docs/architecture/deprecations/legacy-sha-fields.md(1 hunks)docs/architecture/journal-architecture-pivot.md(1 hunks)docs/architecture/tombstone-visual.md(1 hunks)docs/audits/vision-drift.md(1 hunks)docs/charter/Project_Charter.md(1 hunks)docs/cli/README.md(1 hunks)docs/cli/combined_markdown.md(1 hunks)docs/cli/gitmind-cache-rebuild.md(1 hunks)docs/cli/gitmind-install-hooks.md(1 hunks)docs/cli/gitmind-link.md(1 hunks)docs/cli/gitmind-list.md(1 hunks)docs/cli/gitmind.md(1 hunks)docs/code-review/CLAUDE.md(1 hunks)docs/code-reviews/rejected-suggestions/1d234c5614f96272eca5e9607d84b3655080546b_feat-cli-safety-e2e_166_valgrind-suppression-link.md(1 hunks)docs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_angle-includes.md(1 hunks)docs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_consumed-length.md(1 hunks)docs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_e2e-refactor.md(1 hunks)docs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_markdownlint.md(1 hunks)docs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_replace-macros-with-literals.md(1 hunks)docs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_umbrella-safety-include.md(1 hunks)docs/code-reviews/rejected-suggestions/608bc03_main_cstd-c23-only.md(1 hunks)docs/code-reviews/rejected-suggestions/608bc03_main_deprec-macros-augment.md(1 hunks)docs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR164_detached-head-behavior.md(1 hunks)docs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR165_move-test-prototypes-private.md(1 hunks)docs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR165_reserve-extra-byte.md(1 hunks)docs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR166_missing-umbrella-apis.md(1 hunks)docs/deployment/Deployment.md(1 hunks)docs/enforcer/BEFORE_WE_BEGIN.md(1 hunks)docs/enforcer/build-these-in.md(1 hunks)docs/enforcer/dev-journals/2025-06-22-foundations.md(1 hunks)docs/enforcer/dev-journals/2025-06-23-foundations-and-shame.md(1 hunks)docs/enforcer/dev-journals/2026-06-24.md(1 hunks)docs/enforcer/gameplans/01-error-handling-revolution.md(1 hunks)docs/enforcer/gameplans/02-memory-architecture-revolution.md(1 hunks)docs/enforcer/gameplans/03-observability-built-in.md(1 hunks)docs/enforcer/gameplans/04-testing-infrastructure-uplift.md(1 hunks)docs/enforcer/gameplans/05-config-convention-overhaul.md(1 hunks)docs/enforcer/gameplans/06-plugin-extensibility-hooks.md(1 hunks)docs/enforcer/gameplans/07-security-hygiene-as-code.md(1 hunks)docs/enforcer/gameplans/08-devex-internal-cli.md(1 hunks)docs/enforcer/gameplans/09-domain-language-purity.md(1 hunks)docs/enforcer/gameplans/10-future-proofing-without-yagni.md(1 hunks)docs/enforcer/gameplans/11-gitmind-metadata-layer.md(1 hunks)docs/enforcer/reviews/2025-06-22-review.md(1 hunks)docs/enforcer/specs/01-error-types-spec.md(1 hunks)docs/enforcer/specs/02-domain-types-spec.md(1 hunks)docs/enforcer/specs/03-security-primitives-spec.md(1 hunks)docs/operations/Environment_Variables.md(1 hunks)docs/planning/Milestones.md(1 hunks)docs/planning/Product_Roadmap.md(1 hunks)docs/planning/Release_Plans.md(1 hunks)docs/planning/Sprint_Plans.md(1 hunks)docs/quality/Markdown_Style_Guide.md(1 hunks)docs/quality/SOLID_DRY_REPORT.md(1 hunks)docs/quality/TIDY_CLANG_CRUSADE.md(1 hunks)docs/quality/local-ci-parity.md(1 hunks)docs/quality/static-analysis-guide.md(1 hunks)docs/quality/tools-vs-custom-checks.md(1 hunks)docs/requirements/Requirements.md(1 hunks)docs/risk/Risk_Register.md(1 hunks)docs/sitrep/2025-06-24/ci-sitrep.md(1 hunks)docs/specs/Technical_Specifications.md(1 hunks)docs/talk-shop/centralized-cbor-keys-and-public-apis.md(1 hunks)docs/talk-shop/deterministic-merges-crdt-advice.md(1 hunks)docs/talk-shop/hardening-mindset.md(1 hunks)docs/talk-shop/journal-first-cbor-commits.md(1 hunks)docs/talk-shop/oid-first-migration.md(1 hunks)docs/testing/Test_Plan.md(1 hunks)docs/wish-list-features/brain-storms/CLAUDE_DEEP_THOUGHTS_FINAL.md(1 hunks)docs/wish-list-features/brain-storms/plugins.md(1 hunks)docs/wish-list-features/plugins2.0/00-summary.md(1 hunks)docs/wish-list-features/plugins2.0/01-requirements.md(1 hunks)docs/wish-list-features/plugins2.0/02-tech-design.md(1 hunks)docs/wish-list-features/plugins2.0/03-api.md(1 hunks)docs/wish-list-features/plugins2.0/04-test-plan.md(1 hunks)
⛔ Files not processed due to max files limit (6)
- docs/wish-list-features/plugins2.0/05-security.md
- include/gitmind/cbor/constants_cbor.h
- include/gitmind/constants_internal.h
- meson.build
- tools/changelog/add_entry.py
- tools/docs/check_frontmatter.py
💤 Files with no reviewable changes (1)
- core/include/gitmind/constants.h
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}
📄 CodeRabbit inference engine (CLAUDE.md)
NEVER use
NOLINTto suppress clang-tidy warnings; ALWAYS fix the underlying issue
Files:
core/include/gitmind/util/ref.hcore/src/cache/builder.ccore/include/gitmind/types.hcore/src/util/ref.ccore/src/cache/tree_builder.ccore/src/journal/reader.ccore/src/journal/writer.ccore/src/cache/query.c
core/**
📄 CodeRabbit inference engine (AGENTS.md)
Add new code under core/ (C23 library: include/ for public headers, src/ for implementation, tests/ for unit tests)
Files:
core/include/gitmind/util/ref.hcore/src/cache/builder.ccore/include/gitmind/types.hcore/src/util/ref.ccore/src/cache/tree_builder.ccore/src/journal/reader.ccore/src/journal/writer.ccore/src/cache/query.c
{core,src,apps,include}/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
{core,src,apps,include}/**/*.{c,h}: Use C23 with warnings-as-errors; forbid VLAs and variable shadowing; require explicit function prototypes
Follow .clang-format (LLVM-based, 4 spaces, 80 columns, pointer alignment right)
Function and variable names in lower_snake_case with gm_ prefix
Macro names in UPPER_SNAKE case
Type names end with _t
Prefer specific header includes; follow include ordering as enforced by .clang-format
Introduce no new clang-tidy warnings (lint via tools/docker-clang-tidy.sh)
Files:
core/include/gitmind/util/ref.hcore/src/cache/builder.ccore/include/gitmind/types.hcore/src/util/ref.ccore/src/cache/tree_builder.ccore/src/journal/reader.ccore/src/journal/writer.ccore/src/cache/query.c
{include,core,src,apps}/**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
Header guards must begin with GITMIND_ and remain stable
Files:
core/include/gitmind/util/ref.hcore/include/gitmind/types.h
core/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Files:
core/include/gitmind/util/ref.hcore/src/cache/builder.ccore/include/gitmind/types.hcore/src/util/ref.ccore/src/cache/tree_builder.ccore/src/journal/reader.ccore/src/journal/writer.ccore/src/cache/query.c
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Files:
docs/cli/gitmind-install-hooks.mddocs/architecture/attribution-system.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_e2e-refactor.mddocs/wish-list-features/plugins2.0/00-summary.mddocs/architecture/journal-architecture-pivot.mddocs/enforcer/gameplans/10-future-proofing-without-yagni.mddocs/Legacy_Mapping.mddocs/enforcer/gameplans/07-security-hygiene-as-code.mddocs/architecture/attribution-integration-guide.mddocs/adult_swim.mddocs/architecture/augments-system.mddocs/testing/Test_Plan.mddocs/architecture/attribution-use-cases.mddocs/cli/gitmind-list.mddocs/planning/Product_Roadmap.mddocs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR166_missing-umbrella-apis.mddocs/planning/Sprint_Plans.mddocs/quality/local-ci-parity.mddocs/risk/Risk_Register.mddocs/enforcer/gameplans/01-error-handling-revolution.mddocs/architecture/MODULAR_RESTRUCTURE_PLAN.mddocs/enforcer/gameplans/03-observability-built-in.mddocs/wish-list-features/plugins2.0/04-test-plan.mddocs/audits/vision-drift.mddocs/enforcer/gameplans/11-gitmind-metadata-layer.mddocs/wish-list-features/brain-storms/plugins.mddocs/architecture/README.mddocs/enforcer/gameplans/04-testing-infrastructure-uplift.mddocs/enforcer/gameplans/05-config-convention-overhaul.mddocs/architecture/MIGRATION_PHILOSOPHY.mddocs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR165_reserve-extra-byte.mddocs/cli/gitmind-link.mddocs/enforcer/BEFORE_WE_BEGIN.mddocs/enforcer/gameplans/09-domain-language-purity.mddocs/wish-list-features/plugins2.0/01-requirements.mddocs/enforcer/specs/01-error-types-spec.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_angle-includes.mddocs/enforcer/specs/02-domain-types-spec.mddocs/wish-list-features/plugins2.0/03-api.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_replace-macros-with-literals.mddocs/api/gitmind-api-reference.mddocs/quality/static-analysis-guide.mddocs/code-reviews/rejected-suggestions/608bc03_main_deprec-macros-augment.mddocs/enforcer/dev-journals/2026-06-24.mddocs/talk-shop/journal-first-cbor-commits.mddocs/deployment/Deployment.mddocs/CI_STRATEGY.mddocs/quality/Markdown_Style_Guide.mddocs/wish-list-features/plugins2.0/02-tech-design.mddocs/cli/gitmind.mddocs/PRDs/PRD-co-thought-mcp-service.mddocs/quality/tools-vs-custom-checks.mddocs/operations/Environment_Variables.mddocs/planning/Milestones.mddocs/enforcer/gameplans/02-memory-architecture-revolution.mddocs/enforcer/gameplans/06-plugin-extensibility-hooks.mddocs/enforcer/dev-journals/2025-06-22-foundations.mddocs/PRDs/PRD-git-mind-semantics-time-travel-prototype.mddocs/talk-shop/oid-first-migration.mddocs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR165_move-test-prototypes-private.mddocs/requirements/Requirements.mddocs/enforcer/reviews/2025-06-22-review.mddocs/talk-shop/centralized-cbor-keys-and-public-apis.mddocs/adr/0002-docs-reorganization.mddocs/architecture/bitmap-cache-design.mddocs/enforcer/build-these-in.mddocs/code-review/CLAUDE.mddocs/sitrep/2025-06-24/ci-sitrep.mddocs/architecture/deprecations/legacy-sha-fields.mddocs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR164_detached-head-behavior.mddocs/planning/Release_Plans.mddocs/talk-shop/hardening-mindset.mddocs/wish-list-features/brain-storms/CLAUDE_DEEP_THOUGHTS_FINAL.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_markdownlint.mddocs/architecture/System_Architecture.mddocs/cli/combined_markdown.mddocs/enforcer/dev-journals/2025-06-23-foundations-and-shame.mddocs/cli/gitmind-cache-rebuild.mddocs/cli/README.mddocs/README.mddocs/enforcer/gameplans/08-devex-internal-cli.mddocs/specs/Technical_Specifications.mddocs/quality/TIDY_CLANG_CRUSADE.mddocs/enforcer/specs/03-security-primitives-spec.mddocs/code-reviews/rejected-suggestions/608bc03_main_cstd-c23-only.mddocs/quality/SOLID_DRY_REPORT.mddocs/architecture/tombstone-visual.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_umbrella-safety-include.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_consumed-length.mddocs/architecture/cache-migration-oid-only.mddocs/DEV_SETUP.mddocs/talk-shop/deterministic-merges-crdt-advice.mddocs/adr/0001-first-class-semantics.mddocs/code-reviews/rejected-suggestions/1d234c5614f96272eca5e9607d84b3655080546b_feat-cli-safety-e2e_166_valgrind-suppression-link.mddocs/charter/Project_Charter.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Files:
docs/cli/gitmind-install-hooks.mddocs/architecture/attribution-system.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_e2e-refactor.mddocs/wish-list-features/plugins2.0/00-summary.mddocs/architecture/journal-architecture-pivot.mddocs/enforcer/gameplans/10-future-proofing-without-yagni.mddocs/Legacy_Mapping.mddocs/enforcer/gameplans/07-security-hygiene-as-code.mddocs/architecture/attribution-integration-guide.mddocs/adult_swim.mddocs/architecture/augments-system.mddocs/testing/Test_Plan.mddocs/architecture/attribution-use-cases.mddocs/cli/gitmind-list.mddocs/planning/Product_Roadmap.mddocs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR166_missing-umbrella-apis.mddocs/planning/Sprint_Plans.mddocs/quality/local-ci-parity.mddocs/risk/Risk_Register.mddocs/enforcer/gameplans/01-error-handling-revolution.mddocs/architecture/MODULAR_RESTRUCTURE_PLAN.mddocs/enforcer/gameplans/03-observability-built-in.mddocs/wish-list-features/plugins2.0/04-test-plan.mddocs/audits/vision-drift.mddocs/enforcer/gameplans/11-gitmind-metadata-layer.mddocs/wish-list-features/brain-storms/plugins.mddocs/architecture/README.mddocs/enforcer/gameplans/04-testing-infrastructure-uplift.mddocs/enforcer/gameplans/05-config-convention-overhaul.mddocs/architecture/MIGRATION_PHILOSOPHY.mddocs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR165_reserve-extra-byte.mddocs/cli/gitmind-link.mddocs/enforcer/BEFORE_WE_BEGIN.mddocs/enforcer/gameplans/09-domain-language-purity.mddocs/wish-list-features/plugins2.0/01-requirements.mddocs/enforcer/specs/01-error-types-spec.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_angle-includes.mddocs/enforcer/specs/02-domain-types-spec.mddocs/wish-list-features/plugins2.0/03-api.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_replace-macros-with-literals.mddocs/api/gitmind-api-reference.mddocs/quality/static-analysis-guide.mddocs/code-reviews/rejected-suggestions/608bc03_main_deprec-macros-augment.mddocs/enforcer/dev-journals/2026-06-24.mddocs/talk-shop/journal-first-cbor-commits.mddocs/deployment/Deployment.mddocs/CI_STRATEGY.mddocs/quality/Markdown_Style_Guide.mddocs/wish-list-features/plugins2.0/02-tech-design.mddocs/cli/gitmind.mddocs/PRDs/PRD-co-thought-mcp-service.mddocs/quality/tools-vs-custom-checks.mddocs/operations/Environment_Variables.mddocs/planning/Milestones.mddocs/enforcer/gameplans/02-memory-architecture-revolution.mddocs/enforcer/gameplans/06-plugin-extensibility-hooks.mddocs/enforcer/dev-journals/2025-06-22-foundations.mddocs/PRDs/PRD-git-mind-semantics-time-travel-prototype.mddocs/talk-shop/oid-first-migration.mddocs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR165_move-test-prototypes-private.mddocs/requirements/Requirements.mddocs/enforcer/reviews/2025-06-22-review.mddocs/talk-shop/centralized-cbor-keys-and-public-apis.mddocs/adr/0002-docs-reorganization.mddocs/architecture/bitmap-cache-design.mddocs/enforcer/build-these-in.mddocs/code-review/CLAUDE.mddocs/sitrep/2025-06-24/ci-sitrep.mddocs/architecture/deprecations/legacy-sha-fields.mddocs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR164_detached-head-behavior.mddocs/planning/Release_Plans.mddocs/talk-shop/hardening-mindset.mddocs/wish-list-features/brain-storms/CLAUDE_DEEP_THOUGHTS_FINAL.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_markdownlint.mddocs/architecture/System_Architecture.mddocs/cli/combined_markdown.mddocs/enforcer/dev-journals/2025-06-23-foundations-and-shame.mddocs/cli/gitmind-cache-rebuild.mddocs/cli/README.mddocs/README.mddocs/enforcer/gameplans/08-devex-internal-cli.mddocs/specs/Technical_Specifications.mddocs/quality/TIDY_CLANG_CRUSADE.mddocs/enforcer/specs/03-security-primitives-spec.mddocs/code-reviews/rejected-suggestions/608bc03_main_cstd-c23-only.mddocs/quality/SOLID_DRY_REPORT.mddocs/architecture/tombstone-visual.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_umbrella-safety-include.mddocs/code-reviews/rejected-suggestions/4d28721c4b98c6dd29f475d5a1974c2fd2d95a1a_feat-cli-safety-e2e_166_consumed-length.mddocs/architecture/cache-migration-oid-only.mddocs/DEV_SETUP.mddocs/talk-shop/deterministic-merges-crdt-advice.mddocs/adr/0001-first-class-semantics.mddocs/code-reviews/rejected-suggestions/1d234c5614f96272eca5e9607d84b3655080546b_feat-cli-safety-e2e_166_valgrind-suppression-link.mddocs/charter/Project_Charter.md
🧠 Learnings (25)
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/hooks/augment.h : Public hook APIs should use the `gm_hook_` prefix; keep header guard stable to avoid breaking includes
Applied to files:
core/include/gitmind/util/ref.h
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: Tag all memories saved to MEMORY BANKS with at least #git-mind
Applied to files:
docs/cli/gitmind-install-hooks.mddocs/cli/gitmind-list.mddocs/cli/gitmind.mddocs/cli/README.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/*.c : Add strict bounds checking for all CBOR parsing paths (lengths, indices, and buffer limits)
Applied to files:
core/src/cache/builder.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/*.c : Validate allocation sizes before malloc and check the result immediately; avoid patterns that compute size then defer validation
Applied to files:
core/src/cache/builder.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/types.h : Define and consistently use the alias `typedef git_oid gm_oid_t` as the canonical OID type
Applied to files:
core/include/gitmind/types.hdocs/talk-shop/oid-first-migration.mddocs/architecture/cache-migration-oid-only.md
📚 Learning: 2025-09-15T01:21:16.867Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.867Z
Learning: Applies to core/**/*.{c,h} : Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Applied to files:
core/include/gitmind/types.hdocs/talk-shop/oid-first-migration.md
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Run build, tests, clang-tidy (via tools/docker-clang-tidy.sh), and gauntlet locally before proposing changes; keep changes zero-warnings and formatted
Applied to files:
docs/quality/local-ci-parity.mddocs/quality/TIDY_CLANG_CRUSADE.md
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Use Meson/Ninja for build and tests; run lint and gauntlet locally; keep diffs minimal and pass CI with zero new clang-tidy warnings
Applied to files:
docs/quality/local-ci-parity.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/*.c : Do not hardcode CBOR field key magic numbers; use centralized definitions from `gitmind/cbor/keys.h`
Applied to files:
docs/code-reviews/rejected-suggestions/ef52094_migration-finish-core-cleanup_PR165_reserve-extra-byte.mddocs/talk-shop/journal-first-cbor-commits.mddocs/talk-shop/centralized-cbor-keys-and-public-apis.mdcore/src/journal/reader.ccore/src/journal/writer.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h
Applied to files:
docs/api/gitmind-api-reference.mdcore/src/journal/reader.c
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to include/{gitmind.h,gitmind/**/*.h} : Public headers must be umbrella-safe: compile standalone, maintain correct include order, have stable GITMIND_* header guards, and provide extern "C" when included from C++
Applied to files:
docs/api/gitmind-api-reference.mdcore/src/journal/reader.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/hooks/augment.h : Remove or timebox deprecated compatibility macros rather than keeping them indefinitely
Applied to files:
docs/code-reviews/rejected-suggestions/608bc03_main_deprec-macros-augment.md
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to docs/**/*.md : Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Applied to files:
.pre-commit-config.yamldocs/README.mdMakefile
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to **/*.md : Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Applied to files:
docs/quality/Markdown_Style_Guide.mdMakefile
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/cache/*.{c,h} : Maintain consistent OID-centric naming for hash utilities and constants (e.g., `oid_hash()`, `OID_HASH_MULTIPLIER`)
Applied to files:
docs/talk-shop/oid-first-migration.mdcore/src/cache/query.cdocs/architecture/cache-migration-oid-only.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
Applied to files:
docs/talk-shop/oid-first-migration.mdcore/src/cache/query.cdocs/architecture/cache-migration-oid-only.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/edge.h : Avoid struct bloat in `gm_edge_t`; do not store both legacy SHA arrays and OIDs long-term—phase out legacy SHA fields
Applied to files:
docs/talk-shop/oid-first-migration.mddocs/architecture/deprecations/legacy-sha-fields.mdcore/src/journal/reader.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/edge/edge.c : When both OID and SHA are present, validate internal consistency (detect mismatches) rather than silently accepting either
Applied to files:
docs/architecture/deprecations/legacy-sha-fields.md
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: DEVLOGs: write freely about ideas, problems noticed, insights, and memories you want to keep
Applied to files:
docs/wish-list-features/brain-storms/CLAUDE_DEEP_THOUGHTS_FINAL.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/reader.c : Split overly long CBOR decoder functions (e.g., `gm_edge_attributed_decode_cbor_ex`) into smaller units for maintainability
Applied to files:
core/src/journal/reader.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to include/gitmind/**/*.h : Public, namespaced headers live under include/gitmind/
Applied to files:
core/src/journal/reader.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/writer.c : Base64-encode CBOR payloads in commit messages to prevent binary corruption
Applied to files:
core/src/journal/writer.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/meson.build : Do not hardcode `c_std=c23`; detect compiler support or provide a compatible minimum standard with feature checks
Applied to files:
docs/code-reviews/rejected-suggestions/608bc03_main_cstd-c23-only.md
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: NEVER circumvent git hooks
Applied to files:
.githooks/pre-pushdocs/DEV_SETUP.md
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: NEVER alter, disable, or otherwise circumvent git hooks or tests
Applied to files:
docs/DEV_SETUP.md
🧬 Code graph analysis (6)
core/include/gitmind/util/ref.h (1)
core/src/util/ref.c (1)
gm_build_ref(18-31)
core/src/cache/builder.c (1)
core/include/gitmind/security/string.h (1)
gm_snprintf(74-80)
core/src/util/ref.c (1)
core/include/gitmind/security/string.h (1)
gm_snprintf(74-80)
core/src/journal/reader.c (1)
core/src/util/ref.c (1)
gm_build_ref(18-31)
core/src/journal/writer.c (1)
core/src/util/ref.c (1)
gm_build_ref(18-31)
core/src/cache/query.c (1)
core/include/gitmind/security/string.h (1)
gm_snprintf(74-80)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: lint-and-sanitize
| #endif | ||
| #define GM_OID_RAWSZ GIT_OID_RAWSZ | ||
| #define GM_PATH_MAX 256 | ||
| #define GM_PATH_MAX 4096 |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
GM_PATH_MAX = 4096 looks good; verify no lingering doubled buffers or PATH_MAX use.
This aligns with the PR intent. Please sweep for GM_PATH_MAX*2, PATH_MAX, and oversized static buffers to avoid regressions.
Run:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Find doubled buffers and PATH_MAX usage
rg -nP --type=c --type=h -C2 '\bGM_PATH_MAX\s*\*\s*2\b|\bPATH_MAX\b'
# Grep for suspicious large fixed path buffers (may be fine; review hits)
rg -nP --type=c --type=h -C2 '\bchar\s+\w+\s*\[\s*(4096|8192|16384)\s*\]'Length of output: 704
GM_PATH_MAX = 4096 — resolve GM_PATH_MAX*2 usage
- core/src/cache/tree_builder.c:180 —
char full_path[GM_PATH_MAX * 2];Replace with a computed allocation (malloc/asprintf) or compute the required length and cap with GM_PATH_MAX; avoid staticGM_PATH_MAX * 2. - No
PATH_MAXusages found. The only other large static buffer is test-only: core/tests/unit/test_sha256.c:151 (char large_data[8192]).
| char full_path[GM_PATH_MAX]; | ||
| char entry_rel_path[GM_PATH_MAX]; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Unify path buffer sizing; remove doubled buffer.
Goal states “removed doubled buffers.” Here, process_fs_entry uses GM_PATH_MAX while process_directory_entry still uses GM_PATH_MAX*2. Use GM_PATH_MAX in both for consistent bounds/behavior.
- char full_path[GM_PATH_MAX * 2];
+ char full_path[GM_PATH_MAX];Also applies to: 180-180
🤖 Prompt for AI Agents
In core/src/cache/tree_builder.c around lines 58-59 (and also at line 180), the
code currently declares path buffers with inconsistent sizes (some using
GM_PATH_MAX*2); change those declarations so both use GM_PATH_MAX to unify path
buffer sizing, replacing any GM_PATH_MAX*2 instances with GM_PATH_MAX and ensure
any related uses/strncpy/strncat calls respect GM_PATH_MAX bounds.
| static int branch_valid(const char *b) { | ||
| if (!b || !*b) return 0; | ||
| for (const char *p = b; *p; ++p) { | ||
| if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') return 0; | ||
| if (*p == '/') return 0; /* tree path not allowed here */ | ||
| } | ||
| if (b[0] == '.' && b[1] == '.' ) return 0; /* no .. */ | ||
| return 1; | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Harden validator and follow naming convention (gm_ prefix).
Current checks miss several Git refname constraints and the function name violates our gm_ prefix rule. Tighten validation and rename the helper.
Apply:
-static int branch_valid(const char *b) {
- if (!b || !*b) return 0;
- for (const char *p = b; *p; ++p) {
- if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') return 0;
- if (*p == '/') return 0; /* tree path not allowed here */
- }
- if (b[0] == '.' && b[1] == '.' ) return 0; /* no .. */
- return 1;
-}
+static int gm_branch_valid(const char *b) {
+ if (!b || !*b) return 0;
+ char prev = '\0';
+ char last = '\0';
+ for (const unsigned char *p = (const unsigned char *)b; *p; ++p) {
+ unsigned char c = *p;
+ if (c <= 0x20 || c == 0x7F) return 0; /* no control/space */
+ if (c == '/') return 0; /* single-segment only */
+ switch (c) { /* reserved chars */
+ case '~': case '^': case ':': case '?':
+ case '*': case '[': case '\\':
+ return 0;
+ }
+ if (prev == '.' && c == '.') return 0; /* no ".." anywhere */
+ if (prev == '@' && c == '{') return 0; /* no "@{" */
+ prev = (char)c;
+ last = (char)c;
+ }
+ if (last == '.') return 0; /* no trailing '.' */
+ return 1;
+}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| static int branch_valid(const char *b) { | |
| if (!b || !*b) return 0; | |
| for (const char *p = b; *p; ++p) { | |
| if (*p == ' ' || *p == '\t' || *p == '\n' || *p == '\r') return 0; | |
| if (*p == '/') return 0; /* tree path not allowed here */ | |
| } | |
| if (b[0] == '.' && b[1] == '.' ) return 0; /* no .. */ | |
| return 1; | |
| } | |
| static int gm_branch_valid(const char *b) { | |
| if (!b || !*b) return 0; | |
| char prev = '\0'; | |
| char last = '\0'; | |
| for (const unsigned char *p = (const unsigned char *)b; *p; ++p) { | |
| unsigned char c = *p; | |
| if (c <= 0x20 || c == 0x7F) return 0; /* no control/space */ | |
| if (c == '/') return 0; /* single-segment only */ | |
| switch (c) { /* reserved chars */ | |
| case '~': case '^': case ':': case '?': | |
| case '*': case '[': case '\\': | |
| return 0; | |
| } | |
| if (prev == '.' && c == '.') return 0; /* no ".." anywhere */ | |
| if (prev == '@' && c == '{') return 0; /* no "@{" */ | |
| prev = (char)c; | |
| last = (char)c; | |
| } | |
| if (last == '.') return 0; /* no trailing '.' */ | |
| return 1; | |
| } |
🤖 Prompt for AI Agents
In core/src/util/ref.c around lines 8 to 16, rename branch_valid to
gm_branch_valid to follow the gm_ naming convention and harden its validation to
match Git refname constraints: ensure name is non-NULL and non-empty, reject any
ASCII control chars (<= 0x20) or DEL (0x7F), reject spaces/tabs/newlines, reject
characters: '~', '^', ':', '?', '*', '[', '\\', and the sequence "@{", reject
any component separator issues (no leading or trailing '/', no consecutive '/'
sequences), disallow names that start or end with a dot or contain a component
equal to "." or "..", reject names that end with ".lock", and reject names
containing '/' followed by or preceding '.' where that would create invalid
components; update all call sites to use the new gm_branch_valid symbol.
|
Thanks for the thorough pass, CodeRabbit — addressed below and documented per repo policy. Rejected suggestions (documented):
Accepted/queued:
Open point:
|
|
Update: gm_build_ref now allows Git-style refs and validates via libgit2 (git_reference_normalize_name). Rejects leading "refs/" in branch input to prevent double prefixing. Tests updated in core/tests/unit/test_ref_utils.c. |
|
Applied: removed GM_PATH_MAX*2 in core/src/cache/tree_builder.c (now GM_PATH_MAX) and included gitmind/security/string.h for gm_snprintf prototype.]} |
|
CI fix attempt:
If this still trips clang-tidy or coverage thresholds, I will iterate on those logs next. |
|
Docs updated:
Also added test_ref_utils to Meson so CI runs the new ref tests. |
|
CI fixes applied:
I will watch the rerun. If anything else trips (clang-tidy/coverage), I will address next. |
|
Docs/env + local CI rig:
Markdownlint sweep: README fixed; broader repo lint runs via ci-local target. |
…ADME lint fixes - Meson: switch to c2x and move options to meson_options.txt (unblocks setup) - Gauntlet: export GITMIND_DOCKER=1 in gating images - CI local rig: add tools/ci/ci_local.sh + Make target ci-local; mirror C-Core Gate - Docs: env vars (GITMIND_CI_IMAGE, HOOKS_BYPASS), CI strategy note (c2x for C23), ref name validation doc with ToC - README: markdownlint compliance (underscore emphasis/strong, spacing, code fence) - Core: gm_build_ref uses libgit2 validation, allows Git-style shorthands, rejects leading refs/ - Tests: add/enable test_ref_utils; fix tree_builder buffer (GM_PATH_MAX)
There was a problem hiding this comment.
Actionable comments posted: 23
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (16)
core/src/hooks/post-commit.c (1)
76-86: Realloc bug: updated pointer not propagated to callerread_file_entry takes char **files, but calls grow_files_array(&files,...). Any realloc updates only the callee’s local pointer; the caller’s files remains stale, leading to use-after-free/corruption after a grow.
Minimal fix: pass files as char *** and write through.
-static int read_file_entry(char **files, size_t *count, size_t *capacity, - char *line, ssize_t len) { +static int read_file_entry(char ***files, size_t *count, size_t *capacity, + char *line, ssize_t len) { @@ - if (*count >= *capacity) { - int error = grow_files_array(&files, capacity); + if (*count >= *capacity) { + int error = grow_files_array(files, capacity); if (error != GM_OK) { return error; } } @@ - files[*count] = strdup(line); - if (!files[*count]) { + (*files)[*count] = strdup(line); + if (!(*files)[*count]) { return GM_NO_MEMORY; } @@ - (*count)++; + (*count)++; return GM_OK; }And update the call site:
- error = read_file_entry(files, &count, &capacity, line, read); + error = read_file_entry(&files, &count, &capacity, line, read);Also applies to: 118-121
include/gitmind/constants_internal.h (1)
17-22: Consolidate path buffer constants to avoid drift.PATH_BUFFER_SIZE duplicates GM_PATH_MAX (now 4096). Prefer a single source (GM_PATH_MAX) to prevent inconsistencies.
core/include/gitmind/result.h (2)
4-5: Add extern "C" guard for public header umbrella safety.Public headers must be C++‑friendly. Wrap declarations with extern "C".
#ifndef GITMIND_RESULT_H #define GITMIND_RESULT_H + +#ifdef __cplusplus +extern "C" { +#endif @@ -#endif /* GITMIND_RESULT_H */ +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* GITMIND_RESULT_H */
131-139: Fix comment vs. implementation mismatch in GM_TRY.Comment says “uses __auto_type” but the macro uses typeof. Either update the comment or gate the macro to use __auto_type when available and typeof as fallback.
Minimal change (comment only):
- * Uses __auto_type (GNU extension) to work with any result type. + * Uses typeof (GNU/Clang extension) to work with any result type.core/src/hooks/augment.c (2)
158-163: Check ULID generation result.gm_ulid_generate likely returns a status. Fail early if it errors.
- gm_ulid_generate(edge.ulid); + if (gm_ulid_generate(edge.ulid) != GM_OK) { + return GM_ERR_UNKNOWN; + }
26-73: Tighten libgit2 object flow (optional).gm_hook_get_blob_sha does an extra lookup: revparse → id → commit_lookup. You can revparse directly to a commit (or peel) and skip one call. Not blocking.
core/src/edge/edge.c (3)
34-39: Remove NOLINT suppressions; fix root cause instead.NOLINT is forbidden by guidelines.
- // NOLINTNEXTLINE(misc-include-cleaner) ctx->time_ops->clock_gettime(CLOCK_REALTIME, &time_spec); @@ - // NOLINTNEXTLINE(misc-include-cleaner) (void)clock_gettime(CLOCK_REALTIME, &time_spec);
96-109: OID construction may read past src_sha on SHA‑256 builds.git_oid_fromraw reads GIT_OID_RAWSZ bytes; src_sha is GM_SHA1_SIZE. Zero‑pad a local buffer first.
- gm_result_void_t src_result = resolve_sha(ctx, src_path, edge.src_sha); + gm_result_void_t src_result = resolve_sha(ctx, src_path, edge.src_sha); if (!src_result.ok) { return (gm_result_edge_t){.ok = false, .u.err = src_result.u.err}; } - git_oid_fromraw(&edge.src_oid, edge.src_sha); + uint8_t src_raw[GM_OID_RAWSZ]; gm_memset_safe(src_raw, sizeof src_raw, 0, sizeof src_raw); + (void)gm_memcpy_span(src_raw, sizeof src_raw, edge.src_sha, GM_SHA1_SIZE); + git_oid_fromraw(&edge.src_oid, src_raw); @@ - gm_result_void_t tgt_result = resolve_sha(ctx, tgt_path, edge.tgt_sha); + gm_result_void_t tgt_result = resolve_sha(ctx, tgt_path, edge.tgt_sha); if (!tgt_result.ok) { return (gm_result_edge_t){.ok = false, .u.err = tgt_result.u.err}; } - git_oid_fromraw(&edge.tgt_oid, edge.tgt_sha); + uint8_t tgt_raw[GM_OID_RAWSZ]; gm_memset_safe(tgt_raw, sizeof tgt_raw, 0, sizeof tgt_raw); + (void)gm_memcpy_span(tgt_raw, sizeof tgt_raw, edge.tgt_sha, GM_SHA1_SIZE); + git_oid_fromraw(&edge.tgt_oid, tgt_raw);
332-345: Encode includes OID fields but decoder ignores them.Decoding will fail on unknown keys; add OID cases to the switch.
const uint8_t *src_raw = git_oid_raw(&edge->src_oid); const uint8_t *tgt_raw = git_oid_raw(&edge->tgt_oid); if (src_raw == NULL) src_raw = edge->src_sha; /* fallback */ if (tgt_raw == NULL) tgt_raw = edge->tgt_sha; /* fallback */ result = write_cbor_bytes(GM_CBOR_KEY_SRC_OID, buffer, available, &offset, src_raw, GM_OID_RAWSZ);…and in decode_cbor_field:
switch (key) { @@ + case GM_CBOR_KEY_SRC_OID: { + uint8_t raw[GM_OID_RAWSZ]; + gm_result_void_t r = gm_cbor_read_bytes(buffer, offset, len, raw, GM_OID_RAWSZ); + if (!r.ok) return gm_err_void(r.u.err); + git_oid_fromraw(&edge->src_oid, raw); + return gm_ok_void(); + } + case GM_CBOR_KEY_TGT_OID: { + uint8_t raw[GM_OID_RAWSZ]; + gm_result_void_t r = gm_cbor_read_bytes(buffer, offset, len, raw, GM_OID_RAWSZ); + if (!r.ok) return gm_err_void(r.u.err); + git_oid_fromraw(&edge->tgt_oid, raw); + return gm_ok_void(); + }core/src/journal/reader.c (3)
109-113: gm_memset_safe usage is incorrect (missing size args).Pass dst size and count per signature.
- gm_memset_safe(&edge, 0, sizeof(edge)); + gm_memset_safe(&edge, sizeof(edge), 0, sizeof(edge));
325-332: Propagate gm_build_ref error instead of collapsing to BUFFER_TOO_SMALL.Improves diagnosability and aligns with normalized error scheme.
- if (gm_build_ref(ref_name, sizeof(ref_name), GITMIND_EDGES_REF_PREFIX, branch) != GM_OK) { - return GM_ERR_BUFFER_TOO_SMALL; - } + int rc = gm_build_ref(ref_name, sizeof(ref_name), GITMIND_EDGES_REF_PREFIX, branch); + if (rc != GM_OK) { + return rc; + }
56-101: Use gm_ helpers in conversion for consistency (optional).*Replace manual loops with gm_memcpy_span/gm_strcpy_safe.
- for (size_t i = 0; i < GM_SHA1_SIZE; i++) { - attributed->src_sha[i] = legacy->src_sha[i]; - attributed->tgt_sha[i] = legacy->tgt_sha[i]; - } + (void)gm_memcpy_span(attributed->src_sha, GM_SHA1_SIZE, legacy->src_sha, GM_SHA1_SIZE); + (void)gm_memcpy_span(attributed->tgt_sha, GM_SHA1_SIZE, legacy->tgt_sha, GM_SHA1_SIZE); @@ - size_t src_len = strlen(legacy->src_path); - if (src_len >= sizeof(attributed->src_path)) { - src_len = sizeof(attributed->src_path) - 1; - } - for (size_t i = 0; i < src_len; i++) { - attributed->src_path[i] = legacy->src_path[i]; - } - attributed->src_path[src_len] = '\0'; + (void)gm_strcpy_safe(attributed->src_path, sizeof attributed->src_path, legacy->src_path); @@ - size_t tgt_len = strlen(legacy->tgt_path); - if (tgt_len >= sizeof(attributed->tgt_path)) { - tgt_len = sizeof(attributed->tgt_path) - 1; - } - for (size_t i = 0; i < tgt_len; i++) { - attributed->tgt_path[i] = legacy->tgt_path[i]; - } - attributed->tgt_path[tgt_len] = '\0'; + (void)gm_strcpy_safe(attributed->tgt_path, sizeof attributed->tgt_path, legacy->tgt_path); @@ - size_t ulid_len = strlen(legacy->ulid); - if (ulid_len >= sizeof(attributed->ulid)) { - ulid_len = sizeof(attributed->ulid) - 1; - } - for (size_t i = 0; i < ulid_len; i++) { - attributed->ulid[i] = legacy->ulid[i]; - } - attributed->ulid[ulid_len] = '\0'; + (void)gm_strcpy_safe(attributed->ulid, sizeof attributed->ulid, legacy->ulid);core/src/cache/builder.c (1)
151-155: Unify OID hex buffer size constant.Prefer a single constant to avoid SHA-1/SHA‑256 drift.
Apply this diff:
static int oid_to_hex(const gm_oid_t *oid, char *out, size_t out_size) { - if (out_size < SHA_HEX_SIZE) return GM_INVALID_ARG; + if (out_size < GM_CACHE_OID_STRING_SIZE) return GM_INVALID_ARG; (void)git_oid_tostr(out, out_size, oid); return GM_OK; } @@ - char sha_hex[SHA_HEX_SIZE]; + char sha_hex[GM_CACHE_OID_STRING_SIZE];Also applies to: 169-176
core/src/cache/query.c (3)
231-245: Use unified OID hex size.Avoid SHA_HEX_SIZE drift.
Apply this diff:
- char sha_hex[SHA_HEX_SIZE]; + char sha_hex[GM_CACHE_OID_STRING_SIZE]; @@ - git_oid_tostr(sha_hex, sizeof sha_hex, &tmp); + git_oid_tostr(sha_hex, sizeof sha_hex, &tmp);
293-313: Avoid raw memcmp on OIDs in hot path.Prefer git_oid_cmp for correctness and clarity; precompute target OID once to avoid per-edge conversions.
Apply this diff:
-typedef struct { - const uint8_t *target_sha; +typedef struct { + gm_oid_t target_oid; @@ - const uint8_t *edge_sha = state->check_source - ? git_oid_raw(&edge->src_oid) - : git_oid_raw(&edge->tgt_oid); - - /* Check if this edge matches our query */ - if (memcmp(edge_sha, state->target_sha, GM_OID_RAWSZ) == 0) { + const gm_oid_t *edge_oid = state->check_source + ? &edge->src_oid + : &edge->tgt_oid; + if (git_oid_cmp(edge_oid, &state->target_oid) == 0) {And in fallback_journal_scan initialization:
- journal_scan_state_t state = { - .target_sha = sha, - .edges = malloc(INITIAL_EDGE_CAPACITY * sizeof(gm_edge_t)), + journal_scan_state_t state = { + .edges = malloc(INITIAL_EDGE_CAPACITY * sizeof(gm_edge_t)), .capacity = INITIAL_EDGE_CAPACITY, .count = 0, .check_source = check_source}; + git_oid_fromraw(&state.target_oid, sha);
485-493: Build ref with gm_build_ref (consistency and bounds).Unify with the rest of the file.
Apply this diff:
- { - int rn = gm_snprintf(ref_name, sizeof(ref_name), "%s%s", GM_CACHE_REF_PREFIX, branch); - if (rn < 0 || (size_t)rn >= sizeof(ref_name)) { - /* fall back to estimate below */ - rc = -1; - } - } + { + int brc = gm_build_ref(ref_name, sizeof(ref_name), GM_CACHE_REF_PREFIX, branch); + if (brc != GM_OK) { + /* fall back to estimate below */ + rc = -1; + } + }
♻️ Duplicate comments (4)
core/src/cache/tree_builder.c (1)
55-61: Good: unified buffer sizing and safe snprintf.Switched to GM_PATH_MAX and gm_snprintf with bounds checks. This addresses earlier feedback about GM_PATH_MAX*2.
core/src/util/ref.c (1)
11-43: Harden gm_build_ref: clear out on failure and map errors precisely.Prevents partial refs and improves error fidelity.
int gm_build_ref(char *out, size_t out_sz, const char *prefix, const char *branch) { - if (!out || out_sz == 0 || !prefix || !branch) { + if (!out || out_sz == 0 || !prefix || !branch) { return GM_ERR_INVALID_ARGUMENT; } - if (*branch == '\0') { + out[0] = '\0'; + if (*branch == '\0') { return GM_ERR_INVALID_ARGUMENT; } /* Require shorthand branch (no leading "refs/") to avoid double prefixing */ - if (branch[0] == 'r' && branch[1] == 'e' && branch[2] == 'f' && - branch[3] == 's' && branch[4] == '/') { + if (strncmp(branch, "refs/", 5) == 0) { return GM_ERR_INVALID_ARGUMENT; } char candidate[REF_NAME_BUFFER_SIZE]; - int rn = gm_snprintf(candidate, sizeof candidate, "%s%s", prefix, branch); - if (rn < 0 || (size_t)rn >= sizeof candidate) { - return GM_ERR_BUFFER_TOO_SMALL; + int rn = gm_snprintf(candidate, sizeof candidate, "%s%s", prefix, branch); + if (rn < 0) { + return GM_ERR_INVALID_ARGUMENT; + } + if ((size_t)rn >= sizeof candidate) { + return GM_ERR_BUFFER_TOO_SMALL; } char normalized[REF_NAME_BUFFER_SIZE]; int nrc = git_reference_normalize_name( normalized, sizeof normalized, candidate, 0); if (nrc != 0) { return GM_ERR_INVALID_ARGUMENT; } - rn = gm_snprintf(out, out_sz, "%s", normalized); - if (rn < 0 || (size_t)rn >= out_sz) { - return GM_ERR_BUFFER_TOO_SMALL; + rn = gm_snprintf(out, out_sz, "%s", normalized); + if (rn < 0) { + out[0] = '\0'; + return GM_ERR_INVALID_ARGUMENT; + } + if ((size_t)rn >= out_sz) { + out[0] = '\0'; + return GM_ERR_BUFFER_TOO_SMALL; } return GM_OK; }Makefile (2)
27-28: md-verify alias remains redundant.Prior feedback stands; if kept, consider folding in extra checks to justify the alias.
42-42: PHONY list update: acknowledged.No further action given prior decision to keep ordering.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (29)
Makefile(1 hunks)README.md(6 hunks)core/include/gitmind/cache.h(2 hunks)core/include/gitmind/result.h(1 hunks)core/include/gitmind/util/ref.h(1 hunks)core/src/cache/builder.c(8 hunks)core/src/cache/query.c(10 hunks)core/src/cache/tree_builder.c(3 hunks)core/src/edge/edge.c(3 hunks)core/src/hooks/augment.c(2 hunks)core/src/hooks/post-commit.c(2 hunks)core/src/journal/reader.c(5 hunks)core/src/util/ref.c(1 hunks)core/tests/unit/test_cache_shard_distribution.c(1 hunks)core/tests/unit/test_edge_oid_fallback.c(1 hunks)core/tests/unit/test_ref_utils.c(1 hunks)docs/CI_STRATEGY.md(1 hunks)docs/architecture/Ref_Name_Validation.md(1 hunks)docs/code-review/CLAUDE.md(2 hunks)docs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_md-verify-alias.md(1 hunks)docs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_phony-ordering.md(1 hunks)docs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_pre-push-changelog-variants.md(1 hunks)docs/code-reviews/rejected-suggestions/608bc03_main_cstd-c23-only.md(2 hunks)docs/operations/Environment_Variables.md(3 hunks)include/gitmind/constants_internal.h(2 hunks)meson.build(4 hunks)meson_options.txt(1 hunks)tools/ci/ci_local.sh(1 hunks)tools/gauntlet/Dockerfile.gauntlet(2 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}
📄 CodeRabbit inference engine (CLAUDE.md)
NEVER use
NOLINTto suppress clang-tidy warnings; ALWAYS fix the underlying issue
Files:
core/src/hooks/augment.ccore/src/hooks/post-commit.ccore/tests/unit/test_ref_utils.ccore/tests/unit/test_cache_shard_distribution.ccore/include/gitmind/cache.hcore/src/util/ref.ccore/src/edge/edge.ccore/tests/unit/test_edge_oid_fallback.ccore/include/gitmind/util/ref.hinclude/gitmind/constants_internal.hcore/src/journal/reader.ccore/src/cache/builder.ccore/src/cache/tree_builder.ccore/include/gitmind/result.hcore/src/cache/query.c
core/**
📄 CodeRabbit inference engine (AGENTS.md)
Add new code under core/ (C23 library: include/ for public headers, src/ for implementation, tests/ for unit tests)
Files:
core/src/hooks/augment.ccore/src/hooks/post-commit.ccore/tests/unit/test_ref_utils.ccore/tests/unit/test_cache_shard_distribution.ccore/include/gitmind/cache.hcore/src/util/ref.ccore/src/edge/edge.ccore/tests/unit/test_edge_oid_fallback.ccore/include/gitmind/util/ref.hcore/src/journal/reader.ccore/src/cache/builder.ccore/src/cache/tree_builder.ccore/include/gitmind/result.hcore/src/cache/query.c
{core,src,apps,include}/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
{core,src,apps,include}/**/*.{c,h}: Use C23 with warnings-as-errors; forbid VLAs and variable shadowing; require explicit function prototypes
Follow .clang-format (LLVM-based, 4 spaces, 80 columns, pointer alignment right)
Function and variable names in lower_snake_case with gm_ prefix
Macro names in UPPER_SNAKE case
Type names end with _t
Prefer specific header includes; follow include ordering as enforced by .clang-format
Introduce no new clang-tidy warnings (lint via tools/docker-clang-tidy.sh)
Files:
core/src/hooks/augment.ccore/src/hooks/post-commit.ccore/tests/unit/test_ref_utils.ccore/tests/unit/test_cache_shard_distribution.ccore/include/gitmind/cache.hcore/src/util/ref.ccore/src/edge/edge.ccore/tests/unit/test_edge_oid_fallback.ccore/include/gitmind/util/ref.hinclude/gitmind/constants_internal.hcore/src/journal/reader.ccore/src/cache/builder.ccore/src/cache/tree_builder.ccore/include/gitmind/result.hcore/src/cache/query.c
core/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Files:
core/src/hooks/augment.ccore/src/hooks/post-commit.ccore/tests/unit/test_ref_utils.ccore/tests/unit/test_cache_shard_distribution.ccore/include/gitmind/cache.hcore/src/util/ref.ccore/src/edge/edge.ccore/tests/unit/test_edge_oid_fallback.ccore/include/gitmind/util/ref.hcore/src/journal/reader.ccore/src/cache/builder.ccore/src/cache/tree_builder.ccore/include/gitmind/result.hcore/src/cache/query.c
core/tests/unit/test_*.c
📄 CodeRabbit inference engine (AGENTS.md)
Unit tests live in core/tests/unit/ and are named test_.c; keep tests deterministic and isolated
Files:
core/tests/unit/test_ref_utils.ccore/tests/unit/test_cache_shard_distribution.ccore/tests/unit/test_edge_oid_fallback.c
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Files:
docs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_pre-push-changelog-variants.mddocs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_phony-ordering.mddocs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_md-verify-alias.mddocs/architecture/Ref_Name_Validation.mddocs/code-review/CLAUDE.mddocs/operations/Environment_Variables.mddocs/code-reviews/rejected-suggestions/608bc03_main_cstd-c23-only.mddocs/CI_STRATEGY.mdREADME.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Files:
docs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_pre-push-changelog-variants.mddocs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_phony-ordering.mddocs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_md-verify-alias.mddocs/architecture/Ref_Name_Validation.mddocs/code-review/CLAUDE.mddocs/operations/Environment_Variables.mddocs/code-reviews/rejected-suggestions/608bc03_main_cstd-c23-only.mddocs/CI_STRATEGY.md
{include,core,src,apps}/**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
Header guards must begin with GITMIND_ and remain stable
Files:
core/include/gitmind/cache.hcore/include/gitmind/util/ref.hinclude/gitmind/constants_internal.hcore/include/gitmind/result.h
include/gitmind/**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
Place namespaced public headers under include/gitmind/
Files:
include/gitmind/constants_internal.h
include/{gitmind.h,gitmind/**/*.h}
📄 CodeRabbit inference engine (AGENTS.md)
Public headers must be umbrella-safe: compile standalone, maintain correct include order, have stable GITMIND_* header guards, and provide extern "C" when included from C++
Files:
include/gitmind/constants_internal.h
🧠 Learnings (30)
📓 Common learnings
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/**/*.c : Normalize error handling to a single scheme (prefer `GM_OK`/`GM_ERR_*`) and avoid mixing raw libgit2 error codes
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.867Z
Learning: Applies to core/**/*.{c,h} : Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/hooks/augment.h : Public hook APIs should use the `gm_hook_` prefix; keep header guard stable to avoid breaking includes
Applied to files:
core/src/hooks/augment.ccore/src/hooks/post-commit.ccore/include/gitmind/util/ref.h
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/hooks/augment.h : Remove or timebox deprecated compatibility macros rather than keeping them indefinitely
Applied to files:
core/src/hooks/augment.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h
Applied to files:
core/src/hooks/augment.ccore/src/hooks/post-commit.ccore/include/gitmind/cache.hcore/src/edge/edge.ccore/include/gitmind/util/ref.hinclude/gitmind/constants_internal.hcore/src/journal/reader.ccore/src/cache/builder.ccore/src/cache/tree_builder.ccore/src/cache/query.c
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to include/{gitmind.h,gitmind/**/*.h} : Public headers must be umbrella-safe: compile standalone, maintain correct include order, have stable GITMIND_* header guards, and provide extern "C" when included from C++
Applied to files:
core/src/hooks/augment.ccore/src/journal/reader.ccore/src/cache/tree_builder.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/edge.h : Avoid struct bloat in `gm_edge_t`; do not store both legacy SHA arrays and OIDs long-term—phase out legacy SHA fields
Applied to files:
core/src/hooks/augment.ccore/include/gitmind/cache.hcore/src/edge/edge.ccore/tests/unit/test_edge_oid_fallback.cinclude/gitmind/constants_internal.hcore/src/journal/reader.ccore/src/cache/builder.ccore/src/cache/query.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to {include,core/include}/**/*.h : Header guards use GITMIND_* naming
Applied to files:
core/src/hooks/post-commit.ccore/include/gitmind/cache.hcore/src/cache/tree_builder.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/cache/*.{c,h} : Maintain consistent OID-centric naming for hash utilities and constants (e.g., `oid_hash()`, `OID_HASH_MULTIPLIER`)
Applied to files:
core/tests/unit/test_cache_shard_distribution.ccore/include/gitmind/cache.hcore/src/cache/builder.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to core/tests/unit/test_*.c : Unit tests live in core/tests/unit/ and are named test_<module>.c; keep tests deterministic and isolated
Applied to files:
core/tests/unit/test_cache_shard_distribution.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
Applied to files:
core/tests/unit/test_cache_shard_distribution.ccore/include/gitmind/cache.hcore/tests/unit/test_edge_oid_fallback.ccore/src/cache/builder.ccore/src/cache/query.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/types.h : Define and consistently use the alias `typedef git_oid gm_oid_t` as the canonical OID type
Applied to files:
core/include/gitmind/cache.h
📚 Learning: 2025-09-15T01:21:16.867Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.867Z
Learning: Applies to core/**/*.{c,h} : Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Applied to files:
core/include/gitmind/cache.hcore/tests/unit/test_edge_oid_fallback.ccore/src/cache/builder.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Use Meson/Ninja for build and tests; run lint and gauntlet locally; keep diffs minimal and pass CI with zero new clang-tidy warnings
Applied to files:
tools/ci/ci_local.shmeson.build
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Run build, tests, clang-tidy (via tools/docker-clang-tidy.sh), and gauntlet locally before proposing changes; keep changes zero-warnings and formatted
Applied to files:
tools/ci/ci_local.sh
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/*.c : Use bounded string functions (e.g., `gm_snprintf`) and ensure explicit NUL termination on all string operations
Applied to files:
core/src/util/ref.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/edge/edge.c : `gm_edge_equal()` must not use OR-style fallback; if OIDs are present use them exclusively, otherwise compare legacy fields—never consider objects equal when OIDs differ
Applied to files:
core/src/edge/edge.ccore/tests/unit/test_edge_oid_fallback.ccore/src/journal/reader.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/meson.build : Do not hardcode `c_std=c23`; detect compiler support or provide a compatible minimum standard with feature checks
Applied to files:
docs/code-review/CLAUDE.mddocs/code-reviews/rejected-suggestions/608bc03_main_cstd-c23-only.mdmeson.build
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/edge/edge.c : When both OID and SHA are present, validate internal consistency (detect mismatches) rather than silently accepting either
Applied to files:
core/tests/unit/test_edge_oid_fallback.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/*.c : Do not hardcode CBOR field key magic numbers; use centralized definitions from `gitmind/cbor/keys.h`
Applied to files:
include/gitmind/constants_internal.hcore/src/journal/reader.c
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: NEVER alter, disable, or otherwise circumvent git hooks or tests
Applied to files:
docs/operations/Environment_Variables.md
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: NEVER circumvent git hooks
Applied to files:
docs/operations/Environment_Variables.md
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to {core,src,apps,include}/**/*.{c,h} : Use C23 with warnings-as-errors; forbid VLAs and variable shadowing; require explicit function prototypes
Applied to files:
docs/code-reviews/rejected-suggestions/608bc03_main_cstd-c23-only.md
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to {core,include}/**/*.{c,h} : Language: C23 with warnings-as-errors; no VLAs; no variable shadowing; use explicit prototypes
Applied to files:
docs/code-reviews/rejected-suggestions/608bc03_main_cstd-c23-only.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/reader.c : Split overly long CBOR decoder functions (e.g., `gm_edge_attributed_decode_cbor_ex`) into smaller units for maintainability
Applied to files:
core/src/journal/reader.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/*.c : Add strict bounds checking for all CBOR parsing paths (lengths, indices, and buffer limits)
Applied to files:
core/src/journal/reader.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to include/gitmind/**/*.h : Public, namespaced headers live under include/gitmind/
Applied to files:
core/src/journal/reader.ccore/src/cache/tree_builder.c
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to {include,core,src,apps}/**/*.h : Header guards must begin with GITMIND_ and remain stable
Applied to files:
core/src/cache/tree_builder.c
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to **/*.md : Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Applied to files:
Makefile
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to docs/**/*.md : Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Applied to files:
Makefile
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: Tag all memories saved to MEMORY BANKS with at least #git-mind
Applied to files:
README.md
🧬 Code graph analysis (12)
core/src/hooks/augment.c (1)
core/include/gitmind/util/memory.h (1)
gm_strcpy_safe(113-138)
core/src/hooks/post-commit.c (1)
core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)
core/tests/unit/test_ref_utils.c (2)
core/src/util/ref.c (1)
gm_build_ref(11-43)core/include/gitmind/util/memory.h (1)
gm_strcpy_safe(113-138)
core/tests/unit/test_cache_shard_distribution.c (1)
core/tests/unit/test_edge_oid_fallback.c (1)
main(10-36)
core/src/util/ref.c (1)
core/include/gitmind/security/string.h (1)
gm_snprintf(74-80)
core/src/edge/edge.c (2)
core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)core/include/gitmind/util/memory.h (1)
gm_strcpy_safe(113-138)
core/tests/unit/test_edge_oid_fallback.c (1)
core/src/edge/edge.c (1)
gm_edge_equal(130-155)
core/include/gitmind/util/ref.h (1)
core/src/util/ref.c (1)
gm_build_ref(11-43)
core/src/journal/reader.c (3)
core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)core/include/gitmind/util/memory.h (2)
gm_memcpy_span(32-47)gm_strcpy_safe(113-138)core/src/util/ref.c (1)
gm_build_ref(11-43)
core/src/cache/builder.c (3)
core/src/util/ref.c (1)
gm_build_ref(11-43)core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)core/include/gitmind/util/memory.h (1)
gm_strcpy_safe(113-138)
core/include/gitmind/result.h (1)
core/include/gitmind/cache/bitmap.h (1)
nodiscard(44-48)
core/src/cache/query.c (3)
core/src/util/ref.c (1)
gm_build_ref(11-43)core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)core/include/gitmind/util/memory.h (2)
gm_strcpy_safe(113-138)gm_memcpy_span(32-47)
🪛 GitHub Actions: Core Quality Checks
meson.build
[error] 294-294: meson.build:294:17: ERROR: Tried to create target "test_ref_utils", but a target of that name already exists.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Compat Canaries (non-blocking) (gcc-12)
- GitHub Check: Compat Canaries (non-blocking) (clang-19)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
- GitHub Check: Compat Canaries (non-blocking) (clang-18)
🔇 Additional comments (27)
tools/gauntlet/Dockerfile.gauntlet (1)
8-8: LGTM: Explicit container context flagSetting GITMIND_DOCKER=1 in both bases is consistent with the Meson host‑build guard. Ensure no code paths treat this as a security bypass outside CI.
If not already, confirm Meson/build scripts only use GITMIND_DOCKER to relax “host build” checks and not to skip tests.
Also applies to: 119-119
docs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_pre-push-changelog-variants.md (1)
1-33: LGTM: Clear decision recordFront matter looks valid; rationale is concise. Ensure the link passes docs link checks.
Run: make md-lint && tools/docs/check_docs.py --mode link --paths docs
docs/code-review/CLAUDE.md (1)
1-9: LGTM: Build notes align with CI policyFront matter and C23/c2x note are consistent with the CI strategy. Keep this in sync with CI_STRATEGY to avoid drift.
Run: make md-lint && tools/docs/check_docs.py --mode toc --paths docs
Also applies to: 139-139
docs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_phony-ordering.md (1)
1-32: LGTM: Cosmetic-only rejection capturedNo lint blockers anticipated. Include in docs index if applicable.
docs/CI_STRATEGY.md (1)
1-9: LGTM: CI gating and canary split documentedContent matches the introduced compiler matrix and deterministic Docker approach. Mermaid block looks well-formed.
Please run: make md-lint && tools/docs/check_docs.py --mode link --paths docs
Also applies to: 15-46, 48-75
docs/code-reviews/rejected-suggestions/608bc03_main_cstd-c23-only.md (1)
1-31: LGTM: Policy clarified (C23 target via c2x)Note about c2x expressing C23 semantics is accurate and matches CI gating.
meson_options.txt (1)
1-5: Options added — verified usage; confirm defaultsOptions look fine. meson.build reads get_option('enable_io'|'enable_time'|'enable_util'|'enable_utf8') and appends -DGITMIND_ENABLE_* cargs (meson.build lines 49, 52, 55, 58). meson_options.txt sets enable_utf8=true and the others=false — confirm the utf8-on default is intentional.
docs/code-reviews/rejected-suggestions/5965e14_feat-changelog-and-sweep-4_PR169_md-verify-alias.md (1)
1-33: LGTM for archive note.Front matter and rationale read clean; link to the original discussion included. No blockers.
README.md (1)
20-25: LGTM — messaging tweaks and lint-friendly emphasis.Text edits improve clarity and should satisfy markdownlint. No action needed.
core/src/cache/tree_builder.c (1)
176-182: Good: consistent GM_PATH_MAX in directory entry path building.Consistent sizing reduces surprises and matches GM_PATH_MAX=4096.
core/src/hooks/augment.c (1)
85-113: LOOKBACK_LIMIT is defined; confirm GM_AUGMENT_LOOKBACK_LIMIT's numeric value
LOOKBACK_LIMIT is aliased to GM_AUGMENT_LOOKBACK_LIMIT in core/include/gitmind/hooks/augment.h:28 — verify the actual numeric value of GM_AUGMENT_LOOKBACK_LIMIT is intentional and appropriate for journal scans.core/tests/unit/test_ref_utils.c (2)
12-21: Good coverage for valid/invalid branches.Happy path and “refs/heads/*” rejection look correct.
29-35: String copy truncation test is precise.Covers return code and termination semantics well.
core/src/edge/edge.c (1)
186-195: Format function looks correct.Bounds-checked gm_snprintf with clear error mapping.
core/tests/unit/test_edge_oid_fallback.c (1)
27-33: LGTM.Covers both fallback and OID-preferred paths.
core/src/journal/reader.c (1)
154-165: Good migration to gm_ safe copies.*Byte-size checked copies reduce UB risk.
core/include/gitmind/cache.h (1)
13-13: Include gm_oid_t: LGTM.Brings gm_oid_t into scope for public API; matches OID-first direction.
Makefile (2)
38-41: ci-local helper: LGTM.Provides parity with gate; nice.
23-25: Docs checks in md-lint: LGTM.
Confirmed tools/docs/check_frontmatter.py and tools/docs/check_docs.py exist under tools/docs; Makefile invocations are correct.core/src/cache/builder.c (2)
34-35: New includes: LGTM.Ref/ref/memory helpers are appropriate here.
142-149: get_oid_prefix: LGTM.Correct hex fmt, bounds, and NUL-termination.
core/src/cache/query.c (3)
27-28: New includes: LGTM.Consistent with ref/memory helpers.
40-49: get_sha_prefix: LGTM.Correct hex derivation and termination.
104-110: Use gm_build_ref for cache ref: LGTM.Safety improvement over snprintf.
meson.build (3)
116-116: Include order change: LGTM.Public include/ first is consistent with guidelines.
3-3: Verify c_std=c2x support or add fallback (meson.build: line 3).
Verification failed here:cc --versionreturned "cc: command not found". Confirm the target toolchain accepts "c2x" or add a Meson probe that falls back to "c23"/"c17" (e.g., test-compile or detect support and set default_options accordingly).
294-294: Duplicate Meson target 'test_ref_utils' — remove to unblock CI. Remove the duplicate executable('test_ref_utils') in meson.build (line 294) and re-run 'meson setup' to confirm; local verification failed (meson: command not found).
| /* Hash function for OID: lightweight mixing for better distribution */ | ||
| static size_t oid_hash(const gm_oid_t *oid, size_t size) { | ||
| size_t hash = 0; | ||
| const uint8_t *raw = git_oid_raw(oid); | ||
| uint32_t x = 0x9E3779B9u; /* golden ratio */ | ||
| for (int i = 0; i < GM_OID_RAWSZ; i++) { | ||
| hash = (hash * OID_HASH_MULTIPLIER) + raw[i]; | ||
| x ^= raw[i]; | ||
| x *= 0x85EBCA6Bu; /* mix */ | ||
| x ^= (x >> 13); | ||
| } | ||
| return hash % size; | ||
| /* final avalanche */ | ||
| x ^= x >> 16; | ||
| x *= 0x7FEB352Du; | ||
| x ^= x >> 15; | ||
| return (size_t)(x % (uint32_t)size); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Hash: add size>0 guard.
Defensive check avoids UB on modulo if misused.
Apply this diff:
static size_t oid_hash(const gm_oid_t *oid, size_t size) {
+ if (size == 0) return 0;
const uint8_t *raw = git_oid_raw(oid);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /* Hash function for OID: lightweight mixing for better distribution */ | |
| static size_t oid_hash(const gm_oid_t *oid, size_t size) { | |
| size_t hash = 0; | |
| const uint8_t *raw = git_oid_raw(oid); | |
| uint32_t x = 0x9E3779B9u; /* golden ratio */ | |
| for (int i = 0; i < GM_OID_RAWSZ; i++) { | |
| hash = (hash * OID_HASH_MULTIPLIER) + raw[i]; | |
| x ^= raw[i]; | |
| x *= 0x85EBCA6Bu; /* mix */ | |
| x ^= (x >> 13); | |
| } | |
| return hash % size; | |
| /* final avalanche */ | |
| x ^= x >> 16; | |
| x *= 0x7FEB352Du; | |
| x ^= x >> 15; | |
| return (size_t)(x % (uint32_t)size); | |
| } | |
| /* Hash function for OID: lightweight mixing for better distribution */ | |
| static size_t oid_hash(const gm_oid_t *oid, size_t size) { | |
| if (size == 0) return 0; | |
| const uint8_t *raw = git_oid_raw(oid); | |
| uint32_t x = 0x9E3779B9u; /* golden ratio */ | |
| for (int i = 0; i < GM_OID_RAWSZ; i++) { | |
| x ^= raw[i]; | |
| x *= 0x85EBCA6Bu; /* mix */ | |
| x ^= (x >> 13); | |
| } | |
| /* final avalanche */ | |
| x ^= x >> 16; | |
| x *= 0x7FEB352Du; | |
| x ^= x >> 15; | |
| return (size_t)(x % (uint32_t)size); | |
| } |
🤖 Prompt for AI Agents
In core/src/cache/builder.c around lines 72 to 86, the oid_hash function
performs a modulo by size without verifying size>0 which can cause UB; add a
defensive guard at the start of the function that checks if size is zero and
returns a safe default (e.g. 0) before any modulo is performed, otherwise
proceed with the existing hash computation and return the computed value modulo
size.
| if ! command -v docker >/dev/null 2>&1; then | ||
| echo "⚠️ Docker not found. Falling back to host build (override guard)." | ||
| export GITMIND_ALLOW_HOST_BUILD=1 | ||
| CC=${CC:-clang} | ||
| echo "==> Host build with $CC" | ||
| rm -rf build-local | ||
| CC=$CC meson setup build-local | ||
| ninja -C build-local | ||
| ninja -C build-local test | ||
| exit 0 | ||
| fi |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Prefer meson test for clearer logs on host builds.
meson test surfaces failures with --print-errorlogs.
CC=${CC:-clang}
echo "==> Host build with $CC"
rm -rf build-local
CC=$CC meson setup build-local
- ninja -C build-local
- ninja -C build-local test
+ ninja -C build-local
+ meson test -C build-local --print-errorlogs
exit 0🤖 Prompt for AI Agents
In tools/ci/ci_local.sh around lines 21 to 31, the host-build branch runs tests
with "ninja -C build-local test" which doesn't surface detailed failure logs;
replace that test invocation with "meson test -C build-local --print-errorlogs"
so meson prints error logs on failures, ensuring you still configure and build
with meson/ninja as before and then run the meson test command with the
--print-errorlogs flag.
| echo "==> clang-tidy (diff-guard style)" | ||
| cd /workspace | ||
| cp "$BUILD_DIR/compile_commands.json" . || true | ||
| if command -v clang-tidy >/dev/null 2>&1; then | ||
| clang-tidy -quiet -p . --config-file=quality/.clang-tidy \ | ||
| $(git ls-files "core/**/*.c" "core/**/*.h" | grep -v -E "(test_|_test\\.|/tests/|core/src/hooks/)") \ | ||
| | tee clang-tidy-report-full.txt || true | ||
| grep -E "^/.*core/|^core/" clang-tidy-report-full.txt > clang-tidy-report.txt || true | ||
| echo "clang-tidy finished (report: clang-tidy-report.txt)" | ||
| else | ||
| echo "clang-tidy not found in image; skipping" | ||
| fi |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
clang-tidy invocation is fine; handle empty file list safely (optional).
Guard so clang-tidy isn’t called with zero paths.
- if command -v clang-tidy >/dev/null 2>&1; then
- clang-tidy -quiet -p . --config-file=quality/.clang-tidy \
- $(git ls-files "core/**/*.c" "core/**/*.h" | grep -v -E "(test_|_test\\.|/tests/|core/src/hooks/)") \
+ if command -v clang-tidy >/dev/null 2>&1; then
+ FILES=$(git ls-files "core/**/*.c" "core/**/*.h" | grep -v -E "(test_|_test\\.|/tests/|core/src/hooks/)" || true)
+ if [ -n "$FILES" ]; then
+ clang-tidy -quiet -p . --config-file=quality/.clang-tidy $FILES \
| tee clang-tidy-report-full.txt || true
- grep -E "^/.*core/|^core/" clang-tidy-report-full.txt > clang-tidy-report.txt || true
- echo "clang-tidy finished (report: clang-tidy-report.txt)"
+ grep -E "^/.*core/|^core/" clang-tidy-report-full.txt > clang-tidy-report.txt || true
+ echo "clang-tidy finished (report: clang-tidy-report.txt)"
+ else
+ echo "No core/*.c,h files to analyze"
+ fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| echo "==> clang-tidy (diff-guard style)" | |
| cd /workspace | |
| cp "$BUILD_DIR/compile_commands.json" . || true | |
| if command -v clang-tidy >/dev/null 2>&1; then | |
| clang-tidy -quiet -p . --config-file=quality/.clang-tidy \ | |
| $(git ls-files "core/**/*.c" "core/**/*.h" | grep -v -E "(test_|_test\\.|/tests/|core/src/hooks/)") \ | |
| | tee clang-tidy-report-full.txt || true | |
| grep -E "^/.*core/|^core/" clang-tidy-report-full.txt > clang-tidy-report.txt || true | |
| echo "clang-tidy finished (report: clang-tidy-report.txt)" | |
| else | |
| echo "clang-tidy not found in image; skipping" | |
| fi | |
| echo "==> clang-tidy (diff-guard style)" | |
| cd /workspace | |
| cp "$BUILD_DIR/compile_commands.json" . || true | |
| if command -v clang-tidy >/dev/null 2>&1; then | |
| FILES=$(git ls-files "core/**/*.c" "core/**/*.h" | grep -v -E "(test_|_test\\.|/tests/|core/src/hooks/)" || true) | |
| if [ -n "$FILES" ]; then | |
| clang-tidy -quiet -p . --config-file=quality/.clang-tidy $FILES \ | |
| | tee clang-tidy-report-full.txt || true | |
| grep -E "^/.*core/|^core/" clang-tidy-report-full.txt > clang-tidy-report.txt || true | |
| echo "clang-tidy finished (report: clang-tidy-report.txt)" | |
| else | |
| echo "No core/*.c,h files to analyze" | |
| fi | |
| else | |
| echo "clang-tidy not found in image; skipping" | |
| fi |
🤖 Prompt for AI Agents
In tools/ci/ci_local.sh around lines 56 to 67, the script may invoke clang-tidy
with an empty path list; capture the result of git ls-files into a variable,
check if that variable is non-empty, and only run clang-tidy when there are
files to check (otherwise echo a message and skip); keep the existing behavior
of writing reports and grepping them, and ensure the variable is quoted when
expanded to avoid word-splitting issues.
…cs, local CI rig)
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
AGENTS.md(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Files:
AGENTS.md
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/**/*.c : Normalize error handling to a single scheme (prefer `GM_OK`/`GM_ERR_*`) and avoid mixing raw libgit2 error codes
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
- GitHub Check: Compat Canaries (non-blocking) (clang-19)
- GitHub Check: Compat Canaries (non-blocking) (clang-18)
- GitHub Check: Compat Canaries (non-blocking) (gcc-12)
- GitHub Check: lint-and-sanitize
🔇 Additional comments (1)
AGENTS.md (1)
72-79: Entry reads well and matches the PR scope.Good, concise coverage of CI, Meson tweaks, ref validation, safety changes, and docs updates.
| 2025-09-15 | ||
| - CI/CD: Fixed C-Core Gate failures. README now complies with markdownlint (underscore emphasis/strong, blockquote spacing, no inline HTML wrappers, code fence fixes, heading punctuation). Added local CI rig `tools/ci/ci_local.sh` and `make ci-local` to mirror C-Core Gate (markdownlint + docs checks, Dockerized build/tests/E2E, clang-tidy pass). | ||
| - Build: Switched Meson `c_std` from `c23` to `c2x` (Meson-compatible while targeting C23). Moved `option()`s to `meson_options.txt`. Set `GITMIND_DOCKER=1` in gauntlet Dockerfile to satisfy the Meson host-build guard inside gating containers. Registered new unit test target `test_ref_utils` in `meson.build`. | ||
| - Core (refs): `gm_build_ref` now accepts Git-style branch shorthands (slashes allowed), validates the combined ref via libgit2 `git_reference_normalize_name`, and rejects leading `refs/` to prevent double-prefixing. Updated header docs and added unit tests. | ||
| - Core (path safety): Removed `GM_PATH_MAX * 2` buffer in `core/src/cache/tree_builder.c`; now uses `GM_PATH_MAX` and bounded `gm_snprintf`. |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Promote date lines to subheadings and add a blank line before the list (improves TOC and lint).
This makes dates linkable in the generated ToC and satisfies common MD rules for list spacing.
Apply:
-2025-09-15
+### 2025-09-15
+Optionally do the same for the 2025-09-14 block for consistency.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 2025-09-15 | |
| - CI/CD: Fixed C-Core Gate failures. README now complies with markdownlint (underscore emphasis/strong, blockquote spacing, no inline HTML wrappers, code fence fixes, heading punctuation). Added local CI rig `tools/ci/ci_local.sh` and `make ci-local` to mirror C-Core Gate (markdownlint + docs checks, Dockerized build/tests/E2E, clang-tidy pass). | |
| - Build: Switched Meson `c_std` from `c23` to `c2x` (Meson-compatible while targeting C23). Moved `option()`s to `meson_options.txt`. Set `GITMIND_DOCKER=1` in gauntlet Dockerfile to satisfy the Meson host-build guard inside gating containers. Registered new unit test target `test_ref_utils` in `meson.build`. | |
| - Core (refs): `gm_build_ref` now accepts Git-style branch shorthands (slashes allowed), validates the combined ref via libgit2 `git_reference_normalize_name`, and rejects leading `refs/` to prevent double-prefixing. Updated header docs and added unit tests. | |
| - Core (path safety): Removed `GM_PATH_MAX * 2` buffer in `core/src/cache/tree_builder.c`; now uses `GM_PATH_MAX` and bounded `gm_snprintf`. | |
| ### 2025-09-15 | |
| - CI/CD: Fixed C-Core Gate failures. README now complies with markdownlint (underscore emphasis/strong, blockquote spacing, no inline HTML wrappers, code fence fixes, heading punctuation). Added local CI rig `tools/ci/ci_local.sh` and `make ci-local` to mirror C-Core Gate (markdownlint + docs checks, Dockerized build/tests/E2E, clang-tidy pass). | |
| - Build: Switched Meson `c_std` from `c23` to `c2x` (Meson-compatible while targeting C23). Moved `option()`s to `meson_options.txt`. Set `GITMIND_DOCKER=1` in gauntlet Dockerfile to satisfy the Meson host-build guard inside gating containers. Registered new unit test target `test_ref_utils` in `meson.build`. | |
| - Core (refs): `gm_build_ref` now accepts Git-style branch shorthands (slashes allowed), validates the combined ref via libgit2 `git_reference_normalize_name`, and rejects leading `refs/` to prevent double-prefixing. Updated header docs and added unit tests. | |
| - Core (path safety): Removed `GM_PATH_MAX * 2` buffer in `core/src/cache/tree_builder.c`; now uses `GM_PATH_MAX` and bounded `gm_snprintf`. |
🤖 Prompt for AI Agents
In AGENTS.md around lines 72 to 76, the release date line should be promoted to
a Markdown subheading and a blank line must be inserted before the following
bullet list to make the date linkable in the TOC and satisfy markdown lint
rules; change the plain date line into a level-3 (or consistent) heading (e.g.,
"### 2025-09-15") and add one blank line between that heading and the subsequent
list items, and optionally apply the same change to the 2025-09-14 block for
consistency.
There was a problem hiding this comment.
Actionable comments posted: 23
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (24)
core/src/cache/tree_size.c (3)
18-18: Remove NOLINT suppression; refactor to satisfy clang-tidy.Repo policy forbids NOLINT. Split the function or switch to an explicit stack to address recursion/complexity warnings.
Minimal step now:
-/* NOLINTNEXTLINE(misc-no-recursion,readability-function-cognitive-complexity) */ static int calculate_tree_size_recursive(git_repository *repo,Follow-up (recommended): hoist a single git_odb* from the top-level and pass it through recursion to avoid reopening the ODB per blob/tree.
67-81: Handle symlinks and submodules; reuse an opened ODB.Mode check only covers BLOB, skipping LINK and COMMIT (submodule) entries. Also, repeatedly opening the ODB inside the loop is unnecessary overhead.
Apply:
- } else if (mode == GIT_FILEMODE_BLOB) { + } else if (mode == GIT_FILEMODE_BLOB || mode == GIT_FILEMODE_LINK || mode == GIT_FILEMODE_COMMIT) { /* Add blob size */ - git_odb *odb2 = NULL; - ret = git_repository_odb(&odb2, repo); + git_odb *odb2 = NULL; + ret = git_repository_odb(&odb2, repo); if (ret == 0) { size_t blob_size; git_object_t blob_type; ret = git_odb_read_header(&blob_size, &blob_type, odb2, entry_oid); if (ret == 0) { *total_size += blob_size; } git_odb_free(odb2); }Further improvement: open git_odb once before the loop and pass it down to child calls to avoid per-entry opens.
89-93: Validate pointers before use.Guard size_bytes and tree_oid; return GM_ERR_INVALID_ARG (or repo standard) on nulls.
Outside selected lines, add:
if (!repo || !tree_oid || !size_bytes) return GM_ERR_INVALID_ARG;core/tests/unit/test_cache_query.c (2)
9-15: Add stdlib include for setenv (next change) and align with safety guard.You’ll need <stdlib.h> for setenv in this test.
Outside selected lines, add:
#include <stdlib.h>
27-31: Fix failing assert by disabling the safety guard in tests.gm_journal_append likely fails under the host safety guard. Explicitly set GITMIND_SAFETY=off (or GITMIND_DOCKER=1) in the test.
Apply:
int main(void) { printf("test_cache_query... "); git_libgit2_init(); + /* Test-only: bypass host safety guard */ + setenv("GITMIND_SAFETY", "off", 1); + setenv("GITMIND_DOCKER", "1", 1);If gm_journal_append requires a specific branch, ensure the journal writer targets "testq" consistently (or set it in ctx if supported).
docs/operations/CBOR_Debugging.md (1)
1-32: LGTM — front matter present; scope and usage clear.Consider linking to docs/operations/Environment_Variables.md for a single source of truth on runtime flags.
core/src/edge/attributed.c (2)
172-183: Bug: OID bytes fallback is unreachable and can emit zero OIDs.
src_raw/tgt_raware always non‑NULL (struct field address), so the ternary never falls back to legacy SHA. Ife->src_oid/e->tgt_oidare zero, you’ll encode 20 zero bytes.Apply this diff to use proper zero checks and libgit2 accessors, and to guard SHA‑256 builds:
- const uint8_t *src_raw = (const uint8_t *)e->src_oid.id; - const uint8_t *tgt_raw = (const uint8_t *)e->tgt_oid.id; + const uint8_t *src_raw = git_oid_is_zero(&e->src_oid) ? NULL : git_oid_raw(&e->src_oid); + const uint8_t *tgt_raw = git_oid_is_zero(&e->tgt_oid) ? NULL : git_oid_raw(&e->tgt_oid); r = gm_cbor_write_uint(GM_CBOR_KEY_SRC_OID, buffer + offset, avail - offset); if (!r.ok) return gm_err_void(r.u.err); offset += r.u.val; - r = gm_cbor_write_bytes(buffer + offset, avail - offset, src_raw ? src_raw : e->src_sha, GM_OID_RAWSZ); +#if GM_OID_RAWSZ != GM_SHA1_SIZE + if (!src_raw) return gm_err_void(GM_ERROR(GM_ERR_INVALID_ARGUMENT, "Missing src OID in SHA-256 mode")); + r = gm_cbor_write_bytes(buffer + offset, avail - offset, src_raw, GM_OID_RAWSZ); +#else + r = gm_cbor_write_bytes(buffer + offset, avail - offset, src_raw ? src_raw : e->src_sha, GM_OID_RAWSZ); +#endif if (!r.ok) return gm_err_void(r.u.err); offset += r.u.val; r = gm_cbor_write_uint(GM_CBOR_KEY_TGT_OID, buffer + offset, avail - offset); if (!r.ok) return gm_err_void(r.u.err); offset += r.u.val; - r = gm_cbor_write_bytes(buffer + offset, avail - offset, tgt_raw ? tgt_raw : e->tgt_sha, GM_OID_RAWSZ); +#if GM_OID_RAWSZ != GM_SHA1_SIZE + if (!tgt_raw) return gm_err_void(GM_ERROR(GM_ERR_INVALID_ARGUMENT, "Missing tgt OID in SHA-256 mode")); + r = gm_cbor_write_bytes(buffer + offset, avail - offset, tgt_raw, GM_OID_RAWSZ); +#else + r = gm_cbor_write_bytes(buffer + offset, avail - offset, tgt_raw ? tgt_raw : e->tgt_sha, GM_OID_RAWSZ); +#endif if (!r.ok) return gm_err_void(r.u.err); offset += r.u.val;
26-79: “Half‑float” conversion is incorrect; implement true IEEE‑754 binary16 or rename.Scaling by
0x3C00doesn’t produce IEEE‑754 half; it breaks round‑trips and interop.Apply this diff to implement proper binary16 encode/decode (round‑to‑nearest‑even):
-/* Constants for confidence conversion */ -#define CONFIDENCE_SCALE 0x3C00 /* 1.0 in IEEE-754 half-float */ +/* IEEE‑754 binary16 helpers */ +static inline uint16_t gm_float_to_f16(float f) { + union { float f; uint32_t u; } v = { .f = f }; + uint32_t sign = (v.u >> 31) & 0x1; + int32_t exp = (int32_t)((v.u >> 23) & 0xFF) - 127 + 15; + uint32_t mant = v.u & 0x7FFFFF; + if (exp <= 0) { + if (exp < -10) return (uint16_t)(sign << 15); + mant = (mant | 0x800000u) >> (1 - exp); + uint16_t frac = (uint16_t)((mant + 0x1000u) >> 13); + return (uint16_t)((sign << 15) | frac); + } else if (exp >= 0x1F) { + /* Inf/NaN clamp (no NaN payload) */ + return (uint16_t)((sign << 15) | 0x7C00u); + } else { + uint16_t frac = (uint16_t)((mant + 0x1000u) >> 13); + return (uint16_t)((sign << 15) | ((uint16_t)exp << 10) | frac); + } +} + +static inline float gm_f16_to_float(uint16_t h) { + uint32_t sign = (h >> 15) & 0x1; + uint32_t exp = (h >> 10) & 0x1F; + uint32_t mant = h & 0x3FF; + uint32_t u; + if (exp == 0) { + if (mant == 0) u = sign << 31; + else { + /* subnormal */ + while ((mant & 0x400u) == 0) { mant <<= 1; exp--; } + mant &= 0x3FFu; exp++; + u = (sign << 31) | ((exp + 127 - 15) << 23) | (mant << 13); + } + } else if (exp == 0x1F) { + u = (sign << 31) | 0x7F800000u | (mant << 13); + } else { + u = (sign << 31) | ((exp + 127 - 15) << 23) | (mant << 13); + } + union { uint32_t u; float f; } v = { .u = u }; + return v.f; +} @@ -uint16_t gm_confidence_to_half_float(float confidence) { +uint16_t gm_confidence_to_half_float(float confidence) { /* Clamp to valid range */ if (confidence < GM_CONFIDENCE_MIN) { confidence = GM_CONFIDENCE_MIN; } if (confidence > GM_CONFIDENCE_MAX) { confidence = GM_CONFIDENCE_MAX; } - - /* Simple conversion: scale to half-float representation */ - return (uint16_t)(confidence * (float)CONFIDENCE_SCALE); + return gm_float_to_f16(confidence); } @@ -float gm_confidence_from_half_float(uint16_t half_float) { - return (float)half_float / (float)CONFIDENCE_SCALE; -} +float gm_confidence_from_half_float(uint16_t half_float) { + return gm_f16_to_float(half_float); +}If you intended a compact fixed‑point, rename API/comments accordingly to avoid IEEE‑754 claims.
core/src/cache/tree_builder.c (3)
200-207: Mode filter OK. Consider symlink policy explicitness.You skip non-directories; if symlinks should be included/excluded deterministically, document or add a flag.
229-231: Bug: error code is swallowed. Return rc as-is.
return rc < 0 ? GM_ERR_UNKNOWN : GM_OK;converts non‑negative error codes (your GM_ERR_*) into OK.- return rc < 0 ? GM_ERR_UNKNOWN : GM_OK; + return rc;
45-55: Replace git_blob_create_from_workdir(...) with git_blob_create_fromdisk(...) (or pass repo-relative paths).git_blob_create_from_workdir expects a path relative to the repository workdir; builder.c creates an absolute temp dir via mkdtemp (CACHE_TEMP_DIR -> /tmp/...), and gm_build_tree_from_directory passes those absolute paths into add_file_to_tree which calls git_blob_create_from_workdir. Use git_blob_create_fromdisk(&blob_oid, repo, file_path) or ensure dir_path is repo-relative. Locations: core/src/cache/tree_builder.c (add_file_to_tree, ~lines 45–55); core/src/cache/builder.c (cache_prepare_rebuild mkdtemp, ~lines 259–260).
core/src/cache/bitmap.c (4)
102-106: Use length-checked Roaring deserializer to prevent OOB reads.
roaring_bitmap_deserialize()doesn't know the buffer length. Switch to a safe API that takes the payload size; otherwise a truncated or malformed buffer can lead to undefined reads.Apply:
- *bitmap = roaring_bitmap_deserialize((const char *)(buffer + header_size)); + size_t payload_len = size - header_size; +#if defined(ROARING_HAVE_PORTABLE_SAFE) + *bitmap = roaring_bitmap_portable_deserialize_safe( + (const char *)(buffer + header_size), payload_len); +#else + /* Fallback: still use native deserialize, but guard with a minimal size check */ + if (payload_len == 0) { + return GM_ERR_UNKNOWN; + } + *bitmap = roaring_bitmap_deserialize((const char *)(buffer + header_size)); +#endif
165-168: Return a more specific error for invalid file sizes.
GM_ERR_UNKNOWNhides the cause. PreferGM_ERR_INVALID_FORMATfor corrupt/invalid bitmap sizes.- return GM_ERR_UNKNOWN; + return GM_ERR_INVALID_FORMAT;
28-35: Guard against size_t overflow when allocating the array.If cardinality exceeds
SIZE_MAX / sizeof(uint32_t),malloc()may wrap. Add a bounds check and returnNULLwith*count = 0.- uint32_t *array = malloc(cardinality * sizeof(uint32_t)); + if (cardinality > SIZE_MAX / sizeof(uint32_t)) { + *count = 0; + return NULL; + } + uint32_t *array = malloc((size_t)cardinality * sizeof(uint32_t));Also applies to: 34-38
74-78: Differentiate serialization failure from “unknown” errors.A short write from
roaring_bitmap_serializeis a serialization error, not “unknown.” ConsiderGM_ERR_INVALID_FORMAT(or addGM_ERR_SERIALIZE_FAILEDif you have it).- return GM_ERR_UNKNOWN; + return GM_ERR_INVALID_FORMAT;core/src/journal/writer.c (2)
206-208: Preserve failure causes from encoder/commit paths.Set
resultto the specific error beforegoto cleanupto avoid opaqueGM_ERR_UNKNOWN.- if (encoder(edge, cbor_buffer + offset, &cbor_edge_size) != GM_OK) { - goto cleanup; - } + { + int enc_rc = encoder(edge, cbor_buffer + offset, &cbor_edge_size); + if (enc_rc != GM_OK) { result = enc_rc; goto cleanup; } + } ... - if (create_journal_commit(&jctx, cbor_buffer, offset, - &commit_oid) != GM_OK) { - goto cleanup; - } + { + int cr = create_journal_commit(&jctx, cbor_buffer, offset, &commit_oid); + if (cr != GM_OK) { result = cr; goto cleanup; } + } ... - if (create_journal_commit(&jctx, cbor_buffer, offset, &commit_oid) != - GM_OK) { - goto cleanup; - } + { + int cr = create_journal_commit(&jctx, cbor_buffer, offset, &commit_oid); + if (cr != GM_OK) { result = cr; goto cleanup; } + }Also applies to: 215-218, 225-227
284-293: Validaterefwith libgit2 before use.Accepting arbitrary
refrisks invalid ref names. Normalize first; reject invalids.- /* Copy ref name securely */ - size_t ref_len = strlen(ref); - if (ref_len >= sizeof(jctx.ref_name)) { - ref_len = sizeof(jctx.ref_name) - 1; - } - for (size_t i = 0; i < ref_len; i++) { - jctx.ref_name[i] = ref[i]; - } - jctx.ref_name[ref_len] = '\0'; + /* Normalize and validate ref name */ + char normalized[REF_NAME_BUFFER_SIZE]; + int nrc = git_reference_normalize_name( + normalized, sizeof normalized, ref, 0); + if (nrc != 0) { + return GM_ERR_INVALID_ARGUMENT; + } + int rn = gm_snprintf(jctx.ref_name, sizeof jctx.ref_name, "%s", normalized); + if (rn < 0 || (size_t)rn >= sizeof jctx.ref_name) { + return GM_ERR_BUFFER_TOO_SMALL; + }core/src/edge/edge.c (1)
342-351: Encode OIDs or fall back based on zero-ness; NULL check never triggers.
edge->src_oid.idis never NULL. Usegit_oid_is_zero()to choose SHA fallback. Prefer a helper to fetch raw bytes (if available).- const uint8_t *src_raw = (const uint8_t *)edge->src_oid.id; - const uint8_t *tgt_raw = (const uint8_t *)edge->tgt_oid.id; - if (src_raw == NULL) src_raw = edge->src_sha; /* fallback */ - if (tgt_raw == NULL) tgt_raw = edge->tgt_sha; /* fallback */ + const uint8_t *src_raw = git_oid_is_zero(&edge->src_oid) + ? edge->src_sha + : (const uint8_t *)edge->src_oid.id; /* or git_oid_raw(&edge->src_oid) */ + const uint8_t *tgt_raw = git_oid_is_zero(&edge->tgt_oid) + ? edge->tgt_sha + : (const uint8_t *)edge->tgt_oid.id; /* or git_oid_raw(&edge->tgt_oid) */core/src/journal/reader.c (1)
65-105: Prefer safe helpers over manual loops in legacy→attributed copy.Use
gm_memcpy_span/gm_strcpy_safeto reduce hand-rolled loops and keep consistent bounds checks.- for (size_t i = 0; i < GM_SHA1_SIZE; i++) { - attributed->src_sha[i] = legacy->src_sha[i]; - attributed->tgt_sha[i] = legacy->tgt_sha[i]; - } + (void)gm_memcpy_span(attributed->src_sha, GM_SHA1_SIZE, + legacy->src_sha, GM_SHA1_SIZE); + (void)gm_memcpy_span(attributed->tgt_sha, GM_SHA1_SIZE, + legacy->tgt_sha, GM_SHA1_SIZE); ... - size_t src_len = strlen(legacy->src_path); - if (src_len >= sizeof(attributed->src_path)) { - src_len = sizeof(attributed->src_path) - 1; - } - for (size_t i = 0; i < src_len; i++) { - attributed->src_path[i] = legacy->src_path[i]; - } - attributed->src_path[src_len] = '\0'; + (void)gm_strcpy_safe(attributed->src_path, sizeof(attributed->src_path), + legacy->src_path); ... - size_t tgt_len = strlen(legacy->tgt_path); - if (tgt_len >= sizeof(attributed->tgt_path)) { - tgt_len = sizeof(attributed->tgt_path) - 1; - } - for (size_t i = 0; i < tgt_len; i++) { - attributed->tgt_path[i] = legacy->tgt_path[i]; - } - attributed->tgt_path[tgt_len] = '\0'; + (void)gm_strcpy_safe(attributed->tgt_path, sizeof(attributed->tgt_path), + legacy->tgt_path); ... - size_t ulid_len = strlen(legacy->ulid); - if (ulid_len >= sizeof(attributed->ulid)) { - ulid_len = sizeof(attributed->ulid) - 1; - } - for (size_t i = 0; i < ulid_len; i++) { - attributed->ulid[i] = legacy->ulid[i]; - } - attributed->ulid[ulid_len] = '\0'; + (void)gm_strcpy_safe(attributed->ulid, sizeof(attributed->ulid), + legacy->ulid);core/include/gitmind/cbor/cbor.h (1)
4-11: Public header missing extern "C" guards.All public headers must be umbrella-safe; add C++ guards to prevent name mangling.
Apply this diff:
#ifndef GITMIND_CBOR_CBOR_H #define GITMIND_CBOR_CBOR_H #include <gitmind/result.h> #include <stddef.h> #include <stdint.h> +#ifdef __cplusplus +extern "C" { +#endif @@ -#endif /* GITMIND_CBOR_CBOR_H */ +#ifdef __cplusplus +} +#endif + +#endif /* GITMIND_CBOR_CBOR_H */core/src/cache/builder.c (1)
171-179: Check gm_snprintf results (defensive).We’re ignoring truncation here; add return checks to catch path overflow early.
Apply this diff:
- (void)gm_snprintf(path, sizeof(path), "%s/%s/%s.%s", temp_dir, - prefix, sha_hex, suffix); + int rn = gm_snprintf(path, sizeof(path), "%s/%s/%s.%s", temp_dir, + prefix, sha_hex, suffix); + if (rn < 0 || (size_t)rn >= sizeof(path)) { + return GM_ERR_BUFFER_TOO_SMALL; + }core/src/cache/query.c (2)
290-296: Prefer git_oid_cmp over memcmp for OID equality.Per project guidance, compare OIDs via libgit2. Avoid raw memcmp on ids.
Apply this diff:
- const uint8_t *edge_sha = state->check_source - ? (const uint8_t *)edge->src_oid.id - : (const uint8_t *)edge->tgt_oid.id; + const gm_oid_t *edge_oid = state->check_source ? &edge->src_oid : &edge->tgt_oid; @@ - if (memcmp(edge_sha, state->target_sha, GM_OID_RAWSZ) == 0) { + gm_oid_t target_oid; + git_oid_fromraw(&target_oid, state->target_sha); + if (git_oid_cmp(edge_oid, &target_oid) == 0) {This keeps state->target_sha unchanged; only the callback logic is updated.
486-496: Unify ref construction: use gm_build_ref here too.Avoid manual string concat to ensure validation and normalization.
Apply this diff:
- char ref_name[REF_NAME_BUFFER_SIZE]; - { - int rn = gm_snprintf(ref_name, sizeof(ref_name), "%s%s", GM_CACHE_REF_PREFIX, branch); - if (rn < 0 || (size_t)rn >= sizeof(ref_name)) { - /* fall back to estimate below */ - rc = -1; - } - } + char ref_name[REF_NAME_BUFFER_SIZE]; + { + int brc = gm_build_ref(ref_name, sizeof(ref_name), GM_CACHE_REF_PREFIX, branch); + if (brc != GM_OK) { + rc = -1; /* fall back to estimate below */ + } + }meson.build (1)
161-255: Link missing tests against libgit2_dep in meson.buildAdd libgit2_dep to the dependencies array for these test executables in meson.build: test_sha256, test_random, test_edge_equal_semantics, test_journal_safety.
♻️ Duplicate comments (14)
core/src/hooks/post-commit.c (1)
12-12: Use angle brackets for public header include.Prevents accidental local shadowing and follows repo include-ordering.
Apply this diff:
-#include "gitmind/security/memory.h" +#include <gitmind/security/memory.h>core/src/hooks/augment.c (1)
155-156: Handle gm_strcpy_safe truncation instead of ignoring return value.Apply this diff:
- (void)gm_strcpy_safe(edge.src_path, GM_PATH_MAX, file_path); - (void)gm_strcpy_safe(edge.tgt_path, GM_PATH_MAX, file_path); + if (gm_strcpy_safe(edge.src_path, GM_PATH_MAX, file_path) < 0 || + gm_strcpy_safe(edge.tgt_path, GM_PATH_MAX, file_path) < 0) { + return GM_ERR_BUFFER_TOO_SMALL; + }tools/ci/ci_local.sh (3)
20-30: Prefer meson test for clearer logs on host builds.CC=${CC:-clang} echo "==> Host build with $CC" rm -rf build-local CC=$CC meson setup build-local - ninja -C build-local - ninja -C build-local test + ninja -C build-local + meson test -C build-local --print-errorlogs exit 0
53-60: Guard clang-tidy when no files match; quote vars.- if command -v clang-tidy >/dev/null 2>&1; then - clang-tidy -quiet -p . --config-file=quality/.clang-tidy \ - $(git ls-files "core/**/*.c" "core/**/*.h" | grep -v -E "(test_|_test\\.|/tests/|core/src/hooks/)") \ - | tee clang-tidy-report-full.txt || true - grep -E "^/.*core/|^core/" clang-tidy-report-full.txt > clang-tidy-report.txt || true - echo "clang-tidy finished (report: clang-tidy-report.txt)" + if command -v clang-tidy >/dev/null 2>&1; then + FILES="$(git ls-files "core/**/*.c" "core/**/*.h" | grep -v -E "(test_|_test\\.|/tests/|core/src/hooks/)" || true)" + if [ -n "$FILES" ]; then + clang-tidy -quiet -p . --config-file=quality/.clang-tidy $FILES \ + | tee clang-tidy-report-full.txt || true + grep -E "^/.*core/|^core/" clang-tidy-report-full.txt > clang-tidy-report.txt || true + echo "clang-tidy finished (report: clang-tidy-report.txt)" + else + echo "No core/*.c,h files to analyze" + fi else echo "clang-tidy not found in image; skipping" fi
47-47: Use meson test in container for error logs.- ninja -C "$BUILD_DIR" test + meson test -C "$BUILD_DIR" --print-errorlogsAGENTS.md (2)
96-116: Promote date to an H3 and add a blank line (TOC + lint).Matches earlier guidance; makes dates linkable and satisfies list-spacing rules.
-2025-09-15 +### 2025-09-15 +
145-147: Resolve duplicate “## Agent Activity Log” heading.There are two H2s with the same text (earlier at Line 94). Rename or merge to avoid duplicate-heading lint errors.
-## Agent Activity Log +## Historical Activity Logcore/tests/unit/test_cache_shard_distribution.c (1)
18-46: Type nits: use size_t for indices and related comparisons.Prevents signed/unsigned mismatches and aligns with standard loop patterns.
static void random_oid(gm_oid_t *oid) { uint8_t raw[GM_OID_RAWSZ]; - for (int i = 0; i < GM_OID_RAWSZ; i++) raw[i] = (uint8_t)(lcg_next() & 0xFF); + for (size_t i = 0; i < (size_t)GM_OID_RAWSZ; i++) + raw[i] = (uint8_t)(lcg_next() & 0xFF); git_oid_fromraw(oid, raw); } @@ - for (int i = 0; i < N; i++) { + for (size_t i = 0; i < (size_t)N; i++) { gm_oid_t oid = {0}; random_oid(&oid); const uint8_t *raw = (const uint8_t *)oid.id; buckets[raw[0]]++; } @@ - uint32_t max_bucket = 0; - for (int i = 0; i < 256; i++) { + uint32_t max_bucket = 0; + for (size_t i = 0; i < 256; i++) { if (buckets[i] > max_bucket) max_bucket = buckets[i]; }core/src/edge/edge.c (1)
48-50: gm_memset_safe fix looks correct now.Signature/order is correct; previous arity issue resolved.
docs/operations/Environment_Variables.md (1)
82-88: Strengthen HOOKS_BYPASS guidance (maintainers/emergencies only + reference required).Reiterate prior feedback and add an explicit requirement to reference an issue/PR when bypassing.
- `HOOKS_BYPASS` - - Purpose: Bypass local git hooks (e.g., the pre‑push CHANGELOG guard) in emergencies. + - Purpose: Emergency‑only bypass for local git hooks (e.g., the pre‑push CHANGELOG guard). Maintainers only. - Usage: `HOOKS_BYPASS=1 git push` - - Notes: Do not make a habit of bypassing hooks; update the CHANGELOG instead. + - Notes: Avoid routine use. Prefer updating the CHANGELOG. If used, reference an issue/PR in the push description (e.g., "refs: #123").Optionally enforce this in
.githooks/pre-push: whenHOOKS_BYPASS=1, require a non-emptyISSUE_OR_PRenv var and fail otherwise.core/include/gitmind/cache.h (2)
47-54: Public struct layout change breaks ABI; move new field to the end or bump SONAME.Inserting journal_tip_oid_bin before existing fields reorders the struct. Preserve ABI by appending at tail and keep hex field deprecated.
Apply this diff:
typedef struct { uint64_t journal_tip_time; /**< Timestamp of last processed journal commit */ - gm_oid_t journal_tip_oid_bin; /**< OID of last processed journal commit (preferred) */ - char journal_tip_oid[GM_CACHE_OID_STRING_SIZE]; /**< [DEPRECATED] OID hex string of last processed journal commit */ + char journal_tip_oid[GM_CACHE_OID_STRING_SIZE]; /**< @deprecated Hex OID of last processed journal commit; prefer journal_tip_oid_bin */ uint64_t edge_count; /**< Total edges in cache */ uint64_t build_time_ms; /**< Time to build cache (milliseconds) */ uint32_t shard_bits; /**< Number of bits for sharding */ uint32_t version; /**< Cache format version */ char branch[GM_CACHE_BRANCH_NAME_SIZE]; /**< Branch name */ + gm_oid_t journal_tip_oid_bin; /**< OID of last processed journal commit (preferred) */ } gm_cache_meta_t;If ABI break is acceptable for this release, document and bump the version accordingly instead.
34-35: Branch name size vs. truncation policy: clarify or enlarge.Either increase GM_CACHE_BRANCH_NAME_SIZE or document that callers must pre-validate; otherwise detect overflow and return an error in setters/constructors.
Would you like me to scan for all gm_strcpy_safe(meta.branch, …) callsites and patch them to reject truncation?
core/src/cache/builder.c (2)
74-88: Hash: add size>0 guard and use git_oid_raw().Avoid UB on modulo by zero and prefer libgit2 accessor over struct internals. This was raised previously and remains.
Apply this diff:
/* Hash function for OID: lightweight mixing for better distribution */ static size_t oid_hash(const gm_oid_t *oid, size_t size) { - const uint8_t *raw = (const uint8_t *)oid->id; + if (size == 0) return 0; + const uint8_t *raw = git_oid_raw(oid); uint32_t x = 0x9E3779B9u; /* golden ratio */ for (int i = 0; i < GM_OID_RAWSZ; i++) { x ^= raw[i]; x *= 0x85EBCA6Bu; /* mix */ x ^= (x >> 13); } @@ - return (size_t)(x % (uint32_t)size); + return (size_t)(x % (uint32_t)size); }
469-470: Branch truncation: detect or reject instead of silent truncate.gm_strcpy_safe may truncate 64+ char branches; either increase GM_CACHE_BRANCH_NAME_SIZE or fail fast.
Apply this diff:
- (void)gm_strcpy_safe(meta.branch, GM_CACHE_BRANCH_NAME_SIZE, branch); + if (strlen(branch) >= GM_CACHE_BRANCH_NAME_SIZE) { + rc = GM_ERR_INVALID_ARGUMENT; + goto cleanup; + } + (void)gm_strcpy_safe(meta.branch, GM_CACHE_BRANCH_NAME_SIZE, branch);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (35)
.pre-commit-config.yaml(1 hunks)AGENTS.md(3 hunks)CONTRIBUTING.md(1 hunks)README.md(7 hunks)core/include/gitmind/cache.h(8 hunks)core/include/gitmind/cbor/cbor.h(6 hunks)core/include/gitmind/edge.h(1 hunks)core/include/gitmind/edge_attributed.h(0 hunks)core/include/gitmind/journal.h(6 hunks)core/include/gitmind/result.h(1 hunks)core/include/gitmind/types.h(2 hunks)core/src/cache/bitmap.c(4 hunks)core/src/cache/builder.c(12 hunks)core/src/cache/query.c(18 hunks)core/src/cache/tree_builder.c(7 hunks)core/src/cache/tree_size.c(1 hunks)core/src/edge/attributed.c(2 hunks)core/src/edge/edge.c(7 hunks)core/src/hooks/augment.c(6 hunks)core/src/hooks/post-commit.c(2 hunks)core/src/journal/reader.c(8 hunks)core/src/journal/writer.c(4 hunks)core/tests/unit/test_cache_meta.c(1 hunks)core/tests/unit/test_cache_query.c(1 hunks)core/tests/unit/test_cache_shard_distribution.c(1 hunks)core/tests/unit/test_edge_attributed_cbor.c(1 hunks)core/tests/unit/test_journal_mixed_cbor.c(2 hunks)docs/TECHNICAL.md(1 hunks)docs/operations/CBOR_Debugging.md(1 hunks)docs/operations/Environment_Variables.md(4 hunks)include/gitmind/attribution.h(1 hunks)meson.build(7 hunks)meson_options.txt(1 hunks)tools/ci/ci_local.sh(1 hunks)tools/quality/check_one_thing.py(1 hunks)
💤 Files with no reviewable changes (1)
- core/include/gitmind/edge_attributed.h
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}
📄 CodeRabbit inference engine (CLAUDE.md)
NEVER use
NOLINTto suppress clang-tidy warnings; ALWAYS fix the underlying issue
Files:
core/tests/unit/test_edge_attributed_cbor.ccore/src/cache/tree_size.ccore/tests/unit/test_cache_shard_distribution.ccore/src/hooks/post-commit.ccore/include/gitmind/cbor/cbor.hcore/tests/unit/test_cache_query.ccore/include/gitmind/edge.hinclude/gitmind/attribution.hcore/tests/unit/test_journal_mixed_cbor.ccore/src/edge/attributed.ccore/src/journal/reader.ccore/include/gitmind/types.hcore/src/cache/bitmap.ccore/src/journal/writer.ccore/tests/unit/test_cache_meta.ccore/src/cache/tree_builder.ccore/include/gitmind/cache.hcore/src/cache/query.ccore/include/gitmind/journal.hcore/src/hooks/augment.ccore/src/cache/builder.ccore/src/edge/edge.ccore/include/gitmind/result.h
core/**
📄 CodeRabbit inference engine (AGENTS.md)
Add new code under core/ (C23 library: include/ for public headers, src/ for implementation, tests/ for unit tests)
Files:
core/tests/unit/test_edge_attributed_cbor.ccore/src/cache/tree_size.ccore/tests/unit/test_cache_shard_distribution.ccore/src/hooks/post-commit.ccore/include/gitmind/cbor/cbor.hcore/tests/unit/test_cache_query.ccore/include/gitmind/edge.hcore/tests/unit/test_journal_mixed_cbor.ccore/src/edge/attributed.ccore/src/journal/reader.ccore/include/gitmind/types.hcore/src/cache/bitmap.ccore/src/journal/writer.ccore/tests/unit/test_cache_meta.ccore/src/cache/tree_builder.ccore/include/gitmind/cache.hcore/src/cache/query.ccore/include/gitmind/journal.hcore/src/hooks/augment.ccore/src/cache/builder.ccore/src/edge/edge.ccore/include/gitmind/result.h
{core,src,apps,include}/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
{core,src,apps,include}/**/*.{c,h}: Use C23 with warnings-as-errors; forbid VLAs and variable shadowing; require explicit function prototypes
Follow .clang-format (LLVM-based, 4 spaces, 80 columns, pointer alignment right)
Function and variable names in lower_snake_case with gm_ prefix
Macro names in UPPER_SNAKE case
Type names end with _t
Prefer specific header includes; follow include ordering as enforced by .clang-format
Introduce no new clang-tidy warnings (lint via tools/docker-clang-tidy.sh)
Files:
core/tests/unit/test_edge_attributed_cbor.ccore/src/cache/tree_size.ccore/tests/unit/test_cache_shard_distribution.ccore/src/hooks/post-commit.ccore/include/gitmind/cbor/cbor.hcore/tests/unit/test_cache_query.ccore/include/gitmind/edge.hinclude/gitmind/attribution.hcore/tests/unit/test_journal_mixed_cbor.ccore/src/edge/attributed.ccore/src/journal/reader.ccore/include/gitmind/types.hcore/src/cache/bitmap.ccore/src/journal/writer.ccore/tests/unit/test_cache_meta.ccore/src/cache/tree_builder.ccore/include/gitmind/cache.hcore/src/cache/query.ccore/include/gitmind/journal.hcore/src/hooks/augment.ccore/src/cache/builder.ccore/src/edge/edge.ccore/include/gitmind/result.h
core/tests/unit/test_*.c
📄 CodeRabbit inference engine (AGENTS.md)
Unit tests live in core/tests/unit/ and are named test_.c; keep tests deterministic and isolated
Files:
core/tests/unit/test_edge_attributed_cbor.ccore/tests/unit/test_cache_shard_distribution.ccore/tests/unit/test_cache_query.ccore/tests/unit/test_journal_mixed_cbor.ccore/tests/unit/test_cache_meta.c
core/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Files:
core/tests/unit/test_edge_attributed_cbor.ccore/src/cache/tree_size.ccore/tests/unit/test_cache_shard_distribution.ccore/src/hooks/post-commit.ccore/include/gitmind/cbor/cbor.hcore/tests/unit/test_cache_query.ccore/include/gitmind/edge.hcore/tests/unit/test_journal_mixed_cbor.ccore/src/edge/attributed.ccore/src/journal/reader.ccore/include/gitmind/types.hcore/src/cache/bitmap.ccore/src/journal/writer.ccore/tests/unit/test_cache_meta.ccore/src/cache/tree_builder.ccore/include/gitmind/cache.hcore/src/cache/query.ccore/include/gitmind/journal.hcore/src/hooks/augment.ccore/src/cache/builder.ccore/src/edge/edge.ccore/include/gitmind/result.h
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Files:
docs/operations/CBOR_Debugging.mddocs/TECHNICAL.mddocs/operations/Environment_Variables.mdCONTRIBUTING.mdREADME.mdAGENTS.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Files:
docs/operations/CBOR_Debugging.mddocs/TECHNICAL.mddocs/operations/Environment_Variables.md
{include,core,src,apps}/**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
Header guards must begin with GITMIND_ and remain stable
Files:
core/include/gitmind/cbor/cbor.hcore/include/gitmind/edge.hinclude/gitmind/attribution.hcore/include/gitmind/types.hcore/include/gitmind/cache.hcore/include/gitmind/journal.hcore/include/gitmind/result.h
include/gitmind/**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
Place namespaced public headers under include/gitmind/
Files:
include/gitmind/attribution.h
include/{gitmind.h,gitmind/**/*.h}
📄 CodeRabbit inference engine (AGENTS.md)
Public headers must be umbrella-safe: compile standalone, maintain correct include order, have stable GITMIND_* header guards, and provide extern "C" when included from C++
Files:
include/gitmind/attribution.h
🧠 Learnings (32)
📓 Common learnings
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
Applied to files:
core/tests/unit/test_edge_attributed_cbor.cdocs/TECHNICAL.mdcore/tests/unit/test_cache_shard_distribution.ccore/src/edge/attributed.ccore/include/gitmind/types.hcore/tests/unit/test_cache_meta.ccore/include/gitmind/cache.hcore/src/cache/query.ccore/src/cache/builder.ccore/src/edge/edge.cAGENTS.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/edge/edge.c : `gm_edge_equal()` must not use OR-style fallback; if OIDs are present use them exclusively, otherwise compare legacy fields—never consider objects equal when OIDs differ
Applied to files:
core/tests/unit/test_edge_attributed_cbor.ccore/src/edge/attributed.ccore/src/cache/query.ccore/src/hooks/augment.ccore/src/cache/builder.ccore/src/edge/edge.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/edge.h : Avoid struct bloat in `gm_edge_t`; do not store both legacy SHA arrays and OIDs long-term—phase out legacy SHA fields
Applied to files:
core/tests/unit/test_edge_attributed_cbor.cdocs/TECHNICAL.mdcore/include/gitmind/edge.hinclude/gitmind/attribution.hcore/tests/unit/test_journal_mixed_cbor.ccore/src/edge/attributed.ccore/src/journal/reader.ccore/include/gitmind/types.hcore/src/journal/writer.ccore/include/gitmind/cache.hcore/src/cache/query.ccore/src/hooks/augment.ccore/src/cache/builder.ccore/src/edge/edge.cAGENTS.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/edge/edge.c : When both OID and SHA are present, validate internal consistency (detect mismatches) rather than silently accepting either
Applied to files:
core/tests/unit/test_edge_attributed_cbor.ccore/src/edge/attributed.ccore/src/cache/query.ccore/src/cache/builder.ccore/src/edge/edge.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/reader.c : Split overly long CBOR decoder functions (e.g., `gm_edge_attributed_decode_cbor_ex`) into smaller units for maintainability
Applied to files:
docs/operations/CBOR_Debugging.mdcore/include/gitmind/cbor/cbor.hcore/include/gitmind/edge.hcore/src/edge/attributed.ccore/src/journal/reader.ccore/include/gitmind/cache.hcore/src/edge/edge.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/*.c : Do not hardcode CBOR field key magic numbers; use centralized definitions from `gitmind/cbor/keys.h`
Applied to files:
docs/operations/CBOR_Debugging.mdcore/include/gitmind/cbor/cbor.hcore/tests/unit/test_journal_mixed_cbor.ccore/src/edge/attributed.ccore/src/journal/reader.ccore/src/journal/writer.ccore/include/gitmind/journal.h
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/*.c : Add strict bounds checking for all CBOR parsing paths (lengths, indices, and buffer limits)
Applied to files:
docs/operations/CBOR_Debugging.mdcore/src/journal/reader.ccore/src/journal/writer.ccore/src/cache/builder.c
📚 Learning: 2025-09-15T01:21:16.867Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.867Z
Learning: Applies to core/**/*.{c,h} : Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Applied to files:
docs/TECHNICAL.mdcore/src/edge/attributed.ccore/include/gitmind/types.hcore/include/gitmind/cache.hcore/src/cache/builder.ccore/src/edge/edge.cAGENTS.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/cache/*.{c,h} : Maintain consistent OID-centric naming for hash utilities and constants (e.g., `oid_hash()`, `OID_HASH_MULTIPLIER`)
Applied to files:
core/tests/unit/test_cache_shard_distribution.ccore/src/edge/attributed.ccore/include/gitmind/types.hcore/include/gitmind/cache.hcore/src/cache/query.ccore/src/cache/builder.cAGENTS.md
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to core/tests/unit/test_*.c : Unit tests live in core/tests/unit/ and are named test_<module>.c; keep tests deterministic and isolated
Applied to files:
core/tests/unit/test_cache_shard_distribution.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/hooks/augment.h : Public hook APIs should use the `gm_hook_` prefix; keep header guard stable to avoid breaking includes
Applied to files:
core/src/hooks/post-commit.cinclude/gitmind/attribution.hcore/include/gitmind/types.hcore/include/gitmind/journal.hcore/src/hooks/augment.c
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to include/{gitmind.h,gitmind/**/*.h} : Public headers must be umbrella-safe: compile standalone, maintain correct include order, have stable GITMIND_* header guards, and provide extern "C" when included from C++
Applied to files:
core/src/hooks/post-commit.ccore/tests/unit/test_cache_query.ccore/tests/unit/test_journal_mixed_cbor.ccore/src/journal/reader.ccore/src/cache/tree_builder.ccore/src/hooks/augment.ccore/src/cache/builder.cAGENTS.md
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to {include,core,src,apps}/**/*.h : Header guards must begin with GITMIND_ and remain stable
Applied to files:
core/src/hooks/post-commit.cdocs/operations/Environment_Variables.mdcore/src/cache/builder.cAGENTS.md
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to include/gitmind/**/*.h : Public, namespaced headers live under include/gitmind/
Applied to files:
core/src/hooks/post-commit.ccore/tests/unit/test_cache_query.ccore/src/journal/reader.ccore/src/cache/tree_builder.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to {include,core/include}/**/*.h : Header guards use GITMIND_* naming
Applied to files:
core/src/hooks/post-commit.ccore/tests/unit/test_cache_query.ccore/src/cache/tree_builder.cdocs/operations/Environment_Variables.mdcore/src/cache/builder.c
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to include/gitmind/**/*.h : Place namespaced public headers under include/gitmind/
Applied to files:
core/src/hooks/post-commit.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h
Applied to files:
core/src/hooks/post-commit.ccore/tests/unit/test_cache_query.cinclude/gitmind/attribution.hcore/tests/unit/test_journal_mixed_cbor.ccore/src/journal/reader.ccore/include/gitmind/types.hcore/src/journal/writer.ccore/src/cache/tree_builder.ccore/include/gitmind/cache.hcore/src/cache/query.ccore/include/gitmind/journal.hcore/src/hooks/augment.ccore/src/cache/builder.ccore/src/edge/edge.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to {core,include}/**/*.{c,h} : Formatting: follow .clang-format (LLVM-based, 4 spaces, 80 cols, pointer alignment right); pre-commit enforces clang-format
Applied to files:
core/src/hooks/post-commit.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Run build, tests, clang-tidy (via tools/docker-clang-tidy.sh), and gauntlet locally before proposing changes; keep changes zero-warnings and formatted
Applied to files:
tools/ci/ci_local.shCONTRIBUTING.mdAGENTS.md
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Use Meson/Ninja for build and tests; run lint and gauntlet locally; keep diffs minimal and pass CI with zero new clang-tidy warnings
Applied to files:
tools/ci/ci_local.shCONTRIBUTING.mdmeson.buildAGENTS.md
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to {core,src,apps,include}/**/*.{c,h} : Introduce no new clang-tidy warnings (lint via tools/docker-clang-tidy.sh)
Applied to files:
tools/ci/ci_local.sh
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to docs/**/*.md : Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Applied to files:
.pre-commit-config.yaml
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/types.h : Define and consistently use the alias `typedef git_oid gm_oid_t` as the canonical OID type
Applied to files:
include/gitmind/attribution.hcore/src/edge/attributed.ccore/include/gitmind/types.hcore/include/gitmind/cache.hcore/src/cache/builder.cAGENTS.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/**/*.c : Normalize error handling to a single scheme (prefer `GM_OK`/`GM_ERR_*`) and avoid mixing raw libgit2 error codes
Applied to files:
core/src/cache/bitmap.cAGENTS.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/writer.c : Base64-encode CBOR payloads in commit messages to prevent binary corruption
Applied to files:
core/src/journal/writer.c
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: NEVER alter, disable, or otherwise circumvent git hooks or tests
Applied to files:
docs/operations/Environment_Variables.md
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: NEVER circumvent git hooks
Applied to files:
docs/operations/Environment_Variables.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/hooks/augment.h : Remove or timebox deprecated compatibility macros rather than keeping them indefinitely
Applied to files:
core/src/hooks/augment.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/meson.build : Do not hardcode `c_std=c23`; detect compiler support or provide a compatible minimum standard with feature checks
Applied to files:
meson.build
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/*.c : Use bounded string functions (e.g., `gm_snprintf`) and ensure explicit NUL termination on all string operations
Applied to files:
core/src/cache/builder.c
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: Tag all memories saved to MEMORY BANKS with at least #git-mind
Applied to files:
README.md
🧬 Code graph analysis (13)
core/tests/unit/test_cache_shard_distribution.c (2)
core/tests/unit/test_cache_query.c (1)
main(27-74)core/tests/unit/test_edge_oid_fallback.c (1)
main(10-36)
core/src/hooks/post-commit.c (1)
core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)
core/include/gitmind/cbor/cbor.h (2)
core/src/cbor/cbor.c (6)
gm_cbor_read_uint(122-150)gm_cbor_read_bytes(190-244)gm_cbor_read_text(247-309)gm_cbor_write_uint(312-374)gm_cbor_write_bytes(377-424)gm_cbor_write_text(427-475)core/include/gitmind/result.h (3)
gm_result_void_t(83-85)gm_result_size_t(74-76)gm_result_size_t(99-101)
core/include/gitmind/edge.h (1)
core/src/edge/edge.c (1)
gm_edge_decode_cbor_ex(505-507)
core/src/journal/reader.c (3)
core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)core/include/gitmind/util/memory.h (2)
gm_memcpy_span(32-47)gm_strcpy_safe(113-138)core/src/util/ref.c (1)
gm_build_ref(11-43)
core/src/journal/writer.c (1)
core/src/util/ref.c (1)
gm_build_ref(11-43)
core/include/gitmind/cache.h (2)
core/src/cache/builder.c (1)
gm_cache_rebuild(490-496)core/src/cache/query.c (5)
gm_cache_query_fanout(446-450)gm_cache_query_fanin(453-457)gm_cache_load_meta(97-169)gm_cache_is_stale(172-225)gm_cache_stats(471-516)
core/src/cache/query.c (3)
core/src/util/ref.c (1)
gm_build_ref(11-43)core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)core/include/gitmind/util/memory.h (2)
gm_strcpy_safe(113-138)gm_memcpy_span(32-47)
core/include/gitmind/journal.h (2)
core/src/journal/reader.c (2)
gm_journal_read(356-360)gm_journal_read_attributed(363-367)core/src/journal/writer.c (3)
gm_journal_append(255-259)gm_journal_append_attributed(262-268)gm_journal_create_commit(271-296)
core/src/hooks/augment.c (1)
core/include/gitmind/util/memory.h (1)
gm_strcpy_safe(113-138)
core/src/cache/builder.c (3)
core/src/util/ref.c (1)
gm_build_ref(11-43)core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)core/include/gitmind/util/memory.h (1)
gm_strcpy_safe(113-138)
core/src/edge/edge.c (3)
core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)core/include/gitmind/util/memory.h (1)
gm_strcpy_safe(113-138)core/src/cbor/cbor.c (1)
gm_cbor_read_bytes(190-244)
core/include/gitmind/result.h (1)
core/include/gitmind/cache/bitmap.h (1)
nodiscard(44-48)
🪛 GitHub Actions: Core Quality Checks
core/tests/unit/test_cache_query.c
[error] 51-51: Assertion 'rc == GM_OK' failed in test_cache_query (core/tests/unit/test_cache_query.c:51).
core/tests/unit/test_journal_mixed_cbor.c
[error] 78-78: ASan memory leak detected: 112 byte(s) leaked in test_journal_mixed_cbor.
🪛 GitHub Actions: C-Core Gate
AGENTS.md
[error] 16-16: MD050/strong-style Strong style [Expected: underscore; Actual: asterisk]
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
| - id: docs-frontmatter-check | ||
| name: docs: frontmatter check | ||
| entry: python3 tools/docs/check_frontmatter.py | ||
| language: python | ||
| files: ^docs/.*\.md$ | ||
| - id: one-thing | ||
| name: policy: one-thing (1 file = 1 thing) | ||
| entry: python3 tools/quality/check_one_thing.py | ||
| language: python | ||
| pass_filenames: false | ||
| files: ^(include/|core/include/|core/src/).*(\.(c|h))$ |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Pin Python version for new hooks; consider push-stage for policy gate.
Add language_version: python3 to avoid system-Python drift, and (optionally) run the One‑Thing policy on push as well.
Apply:
- - id: docs-frontmatter-check
+ - id: docs-frontmatter-check
name: docs: frontmatter check
entry: python3 tools/docs/check_frontmatter.py
- language: python
+ language: python
+ language_version: python3
files: ^docs/.*\.md$
- - id: one-thing
+ - id: one-thing
name: policy: one-thing (1 file = 1 thing)
entry: python3 tools/quality/check_one_thing.py
- language: python
+ language: python
+ language_version: python3
pass_filenames: false
files: ^(include/|core/include/|core/src/).*(\.(c|h))$
+ # Optional: also enforce on push
+ # stages: [commit, push]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - id: docs-frontmatter-check | |
| name: docs: frontmatter check | |
| entry: python3 tools/docs/check_frontmatter.py | |
| language: python | |
| files: ^docs/.*\.md$ | |
| - id: one-thing | |
| name: policy: one-thing (1 file = 1 thing) | |
| entry: python3 tools/quality/check_one_thing.py | |
| language: python | |
| pass_filenames: false | |
| files: ^(include/|core/include/|core/src/).*(\.(c|h))$ | |
| - id: docs-frontmatter-check | |
| name: docs: frontmatter check | |
| entry: python3 tools/docs/check_frontmatter.py | |
| language: python | |
| language_version: python3 | |
| files: ^docs/.*\.md$ | |
| - id: one-thing | |
| name: policy: one-thing (1 file = 1 thing) | |
| entry: python3 tools/quality/check_one_thing.py | |
| language: python | |
| language_version: python3 | |
| pass_filenames: false | |
| files: ^(include/|core/include/|core/src/).*(\.(c|h))$ | |
| # Optional: also enforce on push | |
| # stages: [commit, push] |
🤖 Prompt for AI Agents
.pre-commit-config.yaml lines 29-39: the two Python hooks don't pin a Python
runtime; add language_version: python3 under each hook to ensure consistent
interpreter usage, and optionally add stages: [push] to the one-thing hook
(policy: one-thing) if you want it to run at push as well as commit; update the
docs-frontmatter-check and one-thing hook entries accordingly.
| /* Internal extension: decode and report bytes consumed */ | ||
| int gm_edge_decode_cbor_ex(const uint8_t *buffer, size_t len, gm_edge_t *edge, size_t *consumed); | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Don’t expose “internal” symbol in public API without gating.
Either move to an internal header or gate as experimental to avoid locking ABI.
Apply this diff:
-/* Internal extension: decode and report bytes consumed */
-int gm_edge_decode_cbor_ex(const uint8_t *buffer, size_t len, gm_edge_t *edge, size_t *consumed);
+/* Internal extension: decode and report bytes consumed (experimental; not stable API) */
+#ifdef GITMIND_EXPERIMENTAL
+int gm_edge_decode_cbor_ex(const uint8_t *buffer, size_t len,
+ gm_edge_t *edge, size_t *consumed);
+#endifIf kept public, consider a gm_result_* return type for consistency.
🤖 Prompt for AI Agents
In core/include/gitmind/edge.h around lines 106 to 108, the internal helper
gm_edge_decode_cbor_ex is being exposed in the public API; either move this
declaration to an internal header (e.g.,
core/include/gitmind/internal/edge_internal.h) and update callers to include
that internal header, or gate it as experimental by wrapping it with an API
visibility/experimental macro (e.g., GM_EXPERIMENTAL) and documenting it as
non-ABI-stable; if you decide to keep it in the public header, change its
signature to return a gm_result_* style enum for consistency and update all
callers to handle that result type.
| /* Attributes */ | ||
| #if defined(__has_c_attribute) | ||
| # if __has_c_attribute(nodiscard) | ||
| # define GM_NODISCARD [[nodiscard]] | ||
| # else | ||
| # define GM_NODISCARD | ||
| # endif | ||
| #else | ||
| # define GM_NODISCARD | ||
| #endif | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add GCC/Clang fallback for GM_NODISCARD.
If [[nodiscard]] isn’t available and __has_c_attribute is missing, we silently drop the warning. Provide a portable fallback to attribute((warn_unused_result)) to keep guarantees on older compilers.
#if defined(__has_c_attribute)
# if __has_c_attribute(nodiscard)
# define GM_NODISCARD [[nodiscard]]
# else
-# define GM_NODISCARD
+# define GM_NODISCARD
# endif
#else
-# define GM_NODISCARD
+# define GM_NODISCARD
#endif
+
+/* Fallback for compilers without __has_c_attribute but supporting GCC/Clang attrs */
+#ifndef GM_NODISCARD
+# if defined(__GNUC__) || defined(__clang__)
+# define GM_NODISCARD __attribute__((warn_unused_result))
+# else
+# define GM_NODISCARD
+# endif
+#endifCommittable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In core/include/gitmind/result.h around lines 46 to 56, the GM_NODISCARD macro
currently only uses [[nodiscard]] when __has_c_attribute is present and
otherwise becomes empty; add a portable fallback that defines GM_NODISCARD as
__attribute__((warn_unused_result)) when compiling with GCC or Clang (detect via
__has_attribute or compiler built-ins like __GNUC__ or __clang__), otherwise
leave it empty; ensure the checks prefer __has_c_attribute and __has_attribute
if available, then fall back to compiler-specific macros so older GCC/Clang
versions still get a warn-unused-result warning.
| GM_NODISCARD static inline gm_result_void_t gm_ok_void(void) { | ||
| return (gm_result_void_t){.ok = true, .u.val = 0}; | ||
| } | ||
|
|
||
| static inline gm_result_ptr_t gm_ok_ptr(void *val) { | ||
| GM_NODISCARD static inline gm_result_ptr_t gm_ok_ptr(void *val) { | ||
| return (gm_result_ptr_t){.ok = true, .u.val = val}; | ||
| } | ||
|
|
||
| static inline gm_result_int_t gm_ok_int(int val) { | ||
| GM_NODISCARD static inline gm_result_int_t gm_ok_int(int val) { | ||
| return (gm_result_int_t){.ok = true, .u.val = val}; | ||
| } | ||
|
|
||
| static inline gm_result_bool_t gm_ok_bool(bool val) { | ||
| GM_NODISCARD static inline gm_result_bool_t gm_ok_bool(bool val) { | ||
| return (gm_result_bool_t){.ok = true, .u.val = val}; | ||
| } | ||
|
|
||
| static inline gm_result_size_t gm_ok_size(size_t val) { | ||
| GM_NODISCARD static inline gm_result_size_t gm_ok_size(size_t val) { | ||
| return (gm_result_size_t){.ok = true, .u.val = val}; | ||
| } | ||
|
|
||
| static inline gm_result_u32_t gm_ok_u32(uint32_t val) { | ||
| GM_NODISCARD static inline gm_result_u32_t gm_ok_u32(uint32_t val) { | ||
| return (gm_result_u32_t){.ok = true, .u.val = val}; | ||
| } | ||
|
|
||
| /* Error constructors */ | ||
| static inline gm_result_void_t gm_err_void(gm_error_t *err) { | ||
| GM_NODISCARD static inline gm_result_void_t gm_err_void(gm_error_t *err) { | ||
| return (gm_result_void_t){.ok = false, .u.err = err}; | ||
| } | ||
|
|
||
| static inline gm_result_ptr_t gm_err_ptr(gm_error_t *err) { | ||
| GM_NODISCARD static inline gm_result_ptr_t gm_err_ptr(gm_error_t *err) { | ||
| return (gm_result_ptr_t){.ok = false, .u.err = err}; | ||
| } | ||
|
|
||
| static inline gm_result_int_t gm_err_int(gm_error_t *err) { | ||
| GM_NODISCARD static inline gm_result_int_t gm_err_int(gm_error_t *err) { | ||
| return (gm_result_int_t){.ok = false, .u.err = err}; | ||
| } | ||
|
|
||
| static inline gm_result_bool_t gm_err_bool(gm_error_t *err) { | ||
| GM_NODISCARD static inline gm_result_bool_t gm_err_bool(gm_error_t *err) { | ||
| return (gm_result_bool_t){.ok = false, .u.err = err}; | ||
| } | ||
|
|
||
| static inline gm_result_size_t gm_err_size(gm_error_t *err) { | ||
| GM_NODISCARD static inline gm_result_size_t gm_err_size(gm_error_t *err) { | ||
| return (gm_result_size_t){.ok = false, .u.err = err}; | ||
| } | ||
|
|
||
| static inline gm_result_u32_t gm_err_u32(gm_error_t *err) { | ||
| GM_NODISCARD static inline gm_result_u32_t gm_err_u32(gm_error_t *err) { | ||
| return (gm_result_u32_t){.ok = false, .u.err = err}; | ||
| } | ||
|
|
||
| static inline gm_result_u64_t gm_ok_u64(uint64_t val) { | ||
| GM_NODISCARD static inline gm_result_u64_t gm_ok_u64(uint64_t val) { | ||
| return (gm_result_u64_t){.ok = true, .u.val = val}; | ||
| } | ||
|
|
||
| static inline gm_result_u64_t gm_err_u64(gm_error_t *err) { | ||
| GM_NODISCARD static inline gm_result_u64_t gm_err_u64(gm_error_t *err) { | ||
| return (gm_result_u64_t){.ok = false, .u.err = err}; | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Good: consistent [[nodiscard]] on result constructors.
This will surface accidental ignored results at call sites. No functional concerns.
Minor: for readability, keep ok_* group contiguous (move gm_ok_u64 above the “Error constructors” block).
🤖 Prompt for AI Agents
core/include/gitmind/result.h lines 58-113: the gm_ok_u64() constructor is
placed after the error constructors, breaking the contiguous grouping of "ok_*"
functions; move the GM_NODISCARD static inline gm_result_u64_t
gm_ok_u64(uint64_t val) { ... } definition so it appears with the other gm_ok_*
constructors (i.e., above the "/* Error constructors */" comment) and leave
gm_err_u64() in the error constructors block unchanged.
| # Feature toggles | ||
| option('enable_io', type: 'boolean', value: false, description: 'Enable IO public headers') | ||
| option('enable_time', type: 'boolean', value: false, description: 'Enable time public headers') | ||
| option('enable_util', type: 'boolean', value: false, description: 'Enable util public headers') | ||
| option('enable_utf8', type: 'boolean', value: true, description: 'Enable UTF-8 public headers') | ||
|
|
||
| # Safety override (dangerous): allow building on host instead of Docker/CI | ||
| option('force_local_builds', type: 'boolean', value: false, | ||
| description: 'Allow host builds (dangerous; use Docker by default)') |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Consider Meson “feature” options for better tri-state control.
Using type: 'feature' allows enabled/disabled/auto and integrates with dependency handling. Keep defaults the same.
-option('enable_io', type: 'boolean', value: false, description: 'Enable IO public headers')
-option('enable_time', type: 'boolean', value: false, description: 'Enable time public headers')
-option('enable_util', type: 'boolean', value: false, description: 'Enable util public headers')
-option('enable_utf8', type: 'boolean', value: true, description: 'Enable UTF-8 public headers')
+option('enable_io', type: 'feature', value: 'disabled', description: 'Enable IO public headers')
+option('enable_time', type: 'feature', value: 'disabled', description: 'Enable time public headers')
+option('enable_util', type: 'feature', value: 'disabled', description: 'Enable util public headers')
+option('enable_utf8', type: 'feature', value: 'enabled', description: 'Enable UTF-8 public headers')Please confirm meson.build consumes these options via get_option() and handles feature types.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Feature toggles | |
| option('enable_io', type: 'boolean', value: false, description: 'Enable IO public headers') | |
| option('enable_time', type: 'boolean', value: false, description: 'Enable time public headers') | |
| option('enable_util', type: 'boolean', value: false, description: 'Enable util public headers') | |
| option('enable_utf8', type: 'boolean', value: true, description: 'Enable UTF-8 public headers') | |
| # Safety override (dangerous): allow building on host instead of Docker/CI | |
| option('force_local_builds', type: 'boolean', value: false, | |
| description: 'Allow host builds (dangerous; use Docker by default)') | |
| # Feature toggles | |
| option('enable_io', type: 'feature', value: 'disabled', description: 'Enable IO public headers') | |
| option('enable_time', type: 'feature', value: 'disabled', description: 'Enable time public headers') | |
| option('enable_util', type: 'feature', value: 'disabled', description: 'Enable util public headers') | |
| option('enable_utf8', type: 'feature', value: 'enabled', description: 'Enable UTF-8 public headers') | |
| # Safety override (dangerous): allow building on host instead of Docker/CI | |
| option('force_local_builds', type: 'boolean', value: false, | |
| description: 'Allow host builds (dangerous; use Docker by default)') |
| project('git-mind', 'c', | ||
| version: '0.6.0', | ||
| default_options: ['c_std=c23', 'warning_level=3', 'werror=true']) | ||
| default_options: ['c_std=c2x', 'warning_level=3', 'werror=true']) |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Don’t hardcode c_std=c2x; detect and select the highest supported standard.
Hardcoding can break older toolchains or non-GCC/Clang setups. Probe support and add the best flag instead.
-project('git-mind', 'c',
- version: '0.6.0',
- default_options: ['c_std=c2x', 'warning_level=3', 'werror=true'])
+project('git-mind', 'c',
+ version: '0.6.0',
+ default_options: ['warning_level=3', 'werror=true'])
+
+# Select the highest C standard the compiler supports (prefer C23/2x)
+cc = meson.get_compiler('c')
+std_candidates = ['-std=c2x', '-std=gnu2x', '-std=c23', '-std=gnu23']
+std_supported = cc.get_supported_arguments(std_candidates)
+if std_supported.length() == 0
+ error('A C23-capable compiler is required (supports one of: c2x/gnu2x/c23/gnu23).')
+endif
+add_project_arguments(std_supported[0], language: 'c')Committable suggestion skipped: line range outside the PR's diff.
| in_docker = run_command('sh', '-lc', '[ "$GITMIND_DOCKER" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' | ||
| in_ci = run_command('sh', '-lc', '[ -n "$GITHUB_ACTIONS" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' | ||
| env_override = run_command('sh', '-lc', '[ "$GITMIND_ALLOW_HOST_BUILD" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' | ||
| force_local = get_option('force_local_builds') | ||
| if not in_docker and not in_ci and not env_override and not force_local |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Avoid spawning shells to read env; use meson.get_env().
Cheaper, more portable, and easier to reason about.
-in_docker = run_command('sh', '-lc', '[ "$GITMIND_DOCKER" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1'
-in_ci = run_command('sh', '-lc', '[ -n "$GITHUB_ACTIONS" ] && echo 1 || echo 0', check: false).stdout().strip() == '1'
-env_override = run_command('sh', '-lc', '[ "$GITMIND_ALLOW_HOST_BUILD" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1'
+in_docker = meson.get_env('GITMIND_DOCKER') == '1'
+in_ci = meson.get_env('GITHUB_ACTIONS') != ''
+env_override = meson.get_env('GITMIND_ALLOW_HOST_BUILD') == '1'Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In meson.build around lines 8 to 12, the code spawns shells with run_command to
read environment variables (GITMIND_DOCKER, GITHUB_ACTIONS,
GITMIND_ALLOW_HOST_BUILD); replace those run_command calls with
meson.get_env('VAR_NAME') and compare the returned string (or check for
non-empty) to produce the same booleans (e.g., in_docker =
meson.get_env('GITMIND_DOCKER') == '1', in_ci = meson.get_env('GITHUB_ACTIONS')
!= '' or == '1' depending on semantics, env_override =
meson.get_env('GITMIND_ALLOW_HOST_BUILD') == '1'), keep force_local =
get_option('force_local_builds') and the final if condition unchanged so no
shells are spawned and behavior is preserved.
| c_args : ['-include', '../' + hdr], | ||
| ) |
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Make -include header path robust for out-of-tree build dirs.
Using '../' assumes a one-level build dir. Prefer an absolute path via join_paths(meson.source_root(), …).
- c_args : ['-include', '../' + hdr],
+ c_args : ['-include', join_paths(meson.source_root(), hdr)],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| c_args : ['-include', '../' + hdr], | |
| ) | |
| c_args : ['-include', join_paths(meson.source_root(), hdr)], | |
| ) |
🤖 Prompt for AI Agents
In meson.build around lines 363-364, the -include argument currently prepends
'../' to hdr which assumes a single-level out-of-tree build directory; replace
that relative '../' concatenation with an absolute source-root-based path using
join_paths(meson.source_root(), <relative-path-to-header-or-hdr>) and pass that
resulting path to c_args (e.g. build the include path via join_paths and use it
instead of '../' + hdr) so the include works for arbitrary out-of-tree build
locations.
| ROOT = Path(__file__).resolve().parents[2] | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick (assertive)
Remove unused constant ROOT.
Dead code; keep the script minimal.
-ROOT = Path(__file__).resolve().parents[2]📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ROOT = Path(__file__).resolve().parents[2] |
🤖 Prompt for AI Agents
In tools/quality/check_one_thing.py around lines 23 to 24, the constant ROOT is
defined but never used; remove the dead-code declaration. Delete the line that
defines ROOT = Path(__file__).resolve().parents[2] and any associated unused
imports if Path is only required for that constant, keeping the script minimal
and ensuring no other code references ROOT after removal.
…ize cache meta + query tests; add test branch override
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (7)
core/tests/unit/test_journal_safety.c (2)
4-12: Add missing stdlib include (C23: malloc/free prototypes).Without
#include <stdlib.h>, this won’t compile with warnings-as-errors (implicit decls removed in C23).#include <assert.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <sodium.h>
46-90: Add fallback and rel_type tests to close gaps.Cover: (1) both OIDs zero → SHA fallback equal/not-equal, (2) only one side has OIDs → still fallback to SHA, (3) rel_type mismatch.
Add this helper and invoke it from main:
static void test_edge_equal_fallback_and_reltype(void) { printf("test_edge_equal_fallback_and_reltype... "); gm_edge_t x = (gm_edge_t){0}, y = (gm_edge_t){0}; x.rel_type = y.rel_type = GM_REL_IMPLEMENTS; /* No OIDs -> SHA fallback: equal */ memset(x.src_sha, 0x10, GM_SHA1_SIZE); memset(y.src_sha, 0x10, GM_SHA1_SIZE); memset(x.tgt_sha, 0x20, GM_SHA1_SIZE); memset(y.tgt_sha, 0x20, GM_SHA1_SIZE); assert(gm_edge_equal(&x, &y)); /* Only one side has OIDs -> still SHA fallback: equal */ uint8_t raw[GM_OID_RAWSZ]; memset(raw, 0xCC, sizeof raw); git_oid_fromraw(&x.src_oid, raw); git_oid_fromraw(&x.tgt_oid, raw); assert(gm_edge_equal(&x, &y)); /* Fallback path with differing SHAs -> not equal */ memset(y.src_sha, 0x21, GM_SHA1_SIZE); assert(!gm_edge_equal(&x, &y)); /* Relationship type mismatch -> not equal */ y = x; /* equal OIDs/SHAs */ y.rel_type = x.rel_type + 1; assert(!gm_edge_equal(&x, &y)); printf("OK\n"); } /* In main(): after test_edge_equal_oid_preferred(); */ test_edge_equal_fallback_and_reltype();I can push a patch if you prefer.
core/tests/unit/test_cache_query.c (1)
4-8: Include stdlib.h for getenv/putenv prototypes.Prevents implicit decl errors and standardizes across platforms.
#include <assert.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <git2.h>AGENTS.md (1)
38-41: Normalize list indentation.Leading spaces before “- ” can trip linters.
- - Markdown linter: `make md-lint` (check) and `make md-fix` (autofix) — uses `.markdownlint.jsonc` - - Header guards lint: `meson run -C build lint_header_guards` - - Public headers compile check: `ninja -C build header-compile` +- Markdown linter: `make md-lint` (check) and `make md-fix` (autofix) — uses `.markdownlint.jsonc` +- Header guards lint: `meson run -C build lint_header_guards` +- Public headers compile check: `ninja -C build header-compile`core/src/journal/writer.c (1)
105-106: Remove stale “unused” note.cbor_len is used below; the cast is misleading.
- (void)cbor_len; /* Unused for now */meson.build (1)
339-355: Addutil/ref.hto public header compile checks.Ensures the new public API is covered by the standalone header build.
Apply:
'core/include/gitmind/time/time.h', + 'core/include/gitmind/util/ref.h', 'core/include/gitmind/util/memory.h',core/src/edge/edge.c (1)
337-342: Don't treat git_oid.id as nullable — check for zero OIDs and fallback to legacy SHA.git_oid.id is a fixed-size array (never NULL). At core/src/edge/edge.c:337-342 and core/src/edge/attributed.c:173-179 the code tests the casted .id pointer for NULL — that will never be true, so zero OIDs are written as all-zero bytes instead of falling back to src_sha/tgt_sha. Replace the NULL-pointer checks with git_oid_is_zero(&edge->src_oid)/git_oid_is_zero(&edge->tgt_oid) (or an explicit byte-zero check) and use edge->src_sha/edge->tgt_sha when the OID is zero.
♻️ Duplicate comments (12)
AGENTS.md (3)
156-156: Resolve duplicate H2 “Agent Activity Log”.Rename the later section to avoid duplicate-heading lint.
-## Agent Activity Log +## Historical Activity Log
15-18: Fix MD050: use underscores for bold in admonition.> [!WARNING] -> **DO NOT BUILD GITMIND OUTSIDE OF DOCKER** +> __DO NOT BUILD GITMIND OUTSIDE OF DOCKER__
94-98: Promote the date to a subheading and add a blank line (ToC/linking).-2025-09-15 +### 2025-09-15 +core/src/journal/writer.c (1)
52-56: Propagate gm_build_ref’s actual error code.Don’t coerce all failures to BUFFER_TOO_SMALL.
- if (nref != GM_OK) { - return GM_ERR_BUFFER_TOO_SMALL; - } + if (nref != GM_OK) { + return nref; + }core/src/util/ref.c (1)
11-18: Zero output deterministically and map snprintf errors precisely.Avoid partial output on failure; return specific errors.
int gm_build_ref(char *out, size_t out_sz, const char *prefix, const char *branch) { - if (!out || out_sz == 0 || !prefix || !branch) { + if (!out || out_sz == 0 || !prefix || !branch) { return GM_ERR_INVALID_ARGUMENT; } + out[0] = '\0'; if (*branch == '\0') { return GM_ERR_INVALID_ARGUMENT; }docs/operations/Environment_Variables.md (1)
88-94: Tighten HOOKS_BYPASS guidance: maintainers/emergencies only + require an issue/PR reference.Aligns with prior feedback and reduces casual bypass.
Apply:
- `HOOKS_BYPASS` - - Purpose: Bypass local git hooks (e.g., the pre‑push CHANGELOG guard) in emergencies. - - Usage: `HOOKS_BYPASS=1 git push` - - Notes: Do not make a habit of bypassing hooks; update the CHANGELOG instead. + - Purpose: Emergency‑only bypass for local git hooks (e.g., the pre‑push CHANGELOG guard). Maintainers only. + - Usage: `HOOKS_BYPASS=1 ISSUE_OR_PR=#123 git push` + - Notes: Avoid routine use. Prefer updating the CHANGELOG. If used, reference an issue/PR in the push description.Optionally update
.githooks/pre-pushto requireISSUE_OR_PRwhenHOOKS_BYPASSis set; I can provide a patch if desired.meson.build (3)
3-3: Don’t hardcodec_std=c2x; probe and pick the highest supported standard.Prevents toolchain breakage while still preferring C23.
Apply:
-project('git-mind', 'c', - version: '0.6.0', - default_options: ['c_std=c2x', 'warning_level=3', 'werror=true']) +project('git-mind', 'c', + version: '0.6.0', + default_options: ['warning_level=3', 'werror=true'])Then insert after Line 6:
+cc = meson.get_compiler('c') +std_candidates = ['-std=c2x', '-std=gnu2x', '-std=c23', '-std=gnu23'] +std_supported = cc.get_supported_arguments(std_candidates) +if std_supported.length() == 0 + error('A C23-capable compiler is required (supports one of: c2x/gnu2x/c23/gnu23).') +endif +add_project_arguments(std_supported[0], language: 'c')
8-10: Avoid spawning shells for env reads; usemeson.get_env().Simpler, faster, and more portable.
Apply:
-in_docker = run_command('sh', '-lc', '[ "$GITMIND_DOCKER" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' -in_ci = run_command('sh', '-lc', '[ -n "$GITHUB_ACTIONS" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' -env_override = run_command('sh', '-lc', '[ "$GITMIND_ALLOW_HOST_BUILD" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' +in_docker = meson.get_env('GITMIND_DOCKER') == '1' +in_ci = meson.get_env('GITHUB_ACTIONS') != '' +env_override = meson.get_env('GITMIND_ALLOW_HOST_BUILD') == '1'
363-364: Make-includepath robust for out‑of‑tree builds.Use an absolute source‑root path.
Apply:
- c_args : ['-include', '../' + hdr], + c_args : ['-include', join_paths(meson.source_root(), hdr)],core/src/edge/edge.c (3)
47-50: Fix incorrectgm_memset_safeparameter order.The function signature requires
(dst, dstsz, val, n)but the current call passes parameters in the wrong order, which will cause a compilation error.Based on the signature in
core/include/gitmind/security/memory.h, apply this fix:static void edge_init_defaults(gm_edge_t *edge) { - (void)gm_memset_safe(edge, sizeof(gm_edge_t), 0, sizeof(gm_edge_t)); + gm_memset_safe(edge, sizeof(*edge), 0, sizeof(*edge)); edge->confidence = DefaultConfidence; }
135-144: Remove dangerous SHA fallback when OIDs differ.When both OIDs are present and not equal, the function should return false immediately. The current logic incorrectly falls back to comparing legacy SHAs even when OIDs differ, violating the principle documented in learnings.
Apply this fix to enforce OID-first semantics:
- /* Source: if both OIDs present, they must match; otherwise fallback to legacy SHA */ + /* Source: if both OIDs present, they must match; only use SHA when OID missing */ if (!git_oid_is_zero(&edge_a->src_oid) && !git_oid_is_zero(&edge_b->src_oid)) { if (git_oid_cmp(&edge_a->src_oid, &edge_b->src_oid) != 0) { return false; } } else { if (memcmp(edge_a->src_sha, edge_b->src_sha, GM_SHA1_SIZE) != 0) { return false; } }
146-155: Remove dangerous SHA fallback for target OIDs.Same issue as source OIDs - when both target OIDs are present and differ, return false immediately without SHA fallback.
Apply this fix:
- /* Target: same rule as Source */ + /* Target: if both OIDs present, they must match; only use SHA when OID missing */ if (!git_oid_is_zero(&edge_a->tgt_oid) && !git_oid_is_zero(&edge_b->tgt_oid)) { if (git_oid_cmp(&edge_a->tgt_oid, &edge_b->tgt_oid) != 0) { return false; } } else { if (memcmp(edge_a->tgt_sha, edge_b->tgt_sha, GM_SHA1_SIZE) != 0) { return false; } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (9)
AGENTS.md(3 hunks)core/src/edge/edge.c(7 hunks)core/src/journal/writer.c(5 hunks)core/src/util/ref.c(1 hunks)core/tests/unit/test_cache_meta.c(1 hunks)core/tests/unit/test_cache_query.c(2 hunks)core/tests/unit/test_journal_safety.c(1 hunks)docs/operations/Environment_Variables.md(4 hunks)meson.build(7 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}
📄 CodeRabbit inference engine (CLAUDE.md)
NEVER use
NOLINTto suppress clang-tidy warnings; ALWAYS fix the underlying issue
Files:
core/tests/unit/test_journal_safety.ccore/src/util/ref.ccore/src/edge/edge.ccore/tests/unit/test_cache_query.ccore/src/journal/writer.ccore/tests/unit/test_cache_meta.c
core/**
📄 CodeRabbit inference engine (AGENTS.md)
Add new code under core/ (C23 library: include/ for public headers, src/ for implementation, tests/ for unit tests)
Files:
core/tests/unit/test_journal_safety.ccore/src/util/ref.ccore/src/edge/edge.ccore/tests/unit/test_cache_query.ccore/src/journal/writer.ccore/tests/unit/test_cache_meta.c
{core,src,apps,include}/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
{core,src,apps,include}/**/*.{c,h}: Use C23 with warnings-as-errors; forbid VLAs and variable shadowing; require explicit function prototypes
Follow .clang-format (LLVM-based, 4 spaces, 80 columns, pointer alignment right)
Function and variable names in lower_snake_case with gm_ prefix
Macro names in UPPER_SNAKE case
Type names end with _t
Prefer specific header includes; follow include ordering as enforced by .clang-format
Introduce no new clang-tidy warnings (lint via tools/docker-clang-tidy.sh)
Files:
core/tests/unit/test_journal_safety.ccore/src/util/ref.ccore/src/edge/edge.ccore/tests/unit/test_cache_query.ccore/src/journal/writer.ccore/tests/unit/test_cache_meta.c
core/tests/unit/test_*.c
📄 CodeRabbit inference engine (AGENTS.md)
Unit tests live in core/tests/unit/ and are named test_.c; keep tests deterministic and isolated
Files:
core/tests/unit/test_journal_safety.ccore/tests/unit/test_cache_query.ccore/tests/unit/test_cache_meta.c
core/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Files:
core/tests/unit/test_journal_safety.ccore/src/util/ref.ccore/src/edge/edge.ccore/tests/unit/test_cache_query.ccore/src/journal/writer.ccore/tests/unit/test_cache_meta.c
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Files:
AGENTS.mddocs/operations/Environment_Variables.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Files:
docs/operations/Environment_Variables.md
🧠 Learnings (23)
📓 Common learnings
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/edge/edge.c : `gm_edge_equal()` must not use OR-style fallback; if OIDs are present use them exclusively, otherwise compare legacy fields—never consider objects equal when OIDs differ
Applied to files:
core/tests/unit/test_journal_safety.ccore/src/edge/edge.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/edge/edge.c : When both OID and SHA are present, validate internal consistency (detect mismatches) rather than silently accepting either
Applied to files:
core/tests/unit/test_journal_safety.ccore/src/edge/edge.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/edge.h : Avoid struct bloat in `gm_edge_t`; do not store both legacy SHA arrays and OIDs long-term—phase out legacy SHA fields
Applied to files:
core/tests/unit/test_journal_safety.ccore/src/edge/edge.cAGENTS.mdcore/src/journal/writer.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
Applied to files:
core/tests/unit/test_journal_safety.ccore/src/edge/edge.ccore/tests/unit/test_cache_query.cAGENTS.mdcore/tests/unit/test_cache_meta.c
📚 Learning: 2025-09-15T01:21:16.867Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.867Z
Learning: Applies to core/**/*.{c,h} : Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Applied to files:
core/tests/unit/test_journal_safety.ccore/src/edge/edge.cAGENTS.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/*.c : Use bounded string functions (e.g., `gm_snprintf`) and ensure explicit NUL termination on all string operations
Applied to files:
core/src/util/ref.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/reader.c : Split overly long CBOR decoder functions (e.g., `gm_edge_attributed_decode_cbor_ex`) into smaller units for maintainability
Applied to files:
core/src/edge/edge.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h
Applied to files:
core/src/edge/edge.ccore/src/journal/writer.c
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to **/*.md : Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Applied to files:
AGENTS.md
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Use Meson/Ninja for build and tests; run lint and gauntlet locally; keep diffs minimal and pass CI with zero new clang-tidy warnings
Applied to files:
AGENTS.mdmeson.build
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Run build, tests, clang-tidy (via tools/docker-clang-tidy.sh), and gauntlet locally before proposing changes; keep changes zero-warnings and formatted
Applied to files:
AGENTS.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/**/*.c : Normalize error handling to a single scheme (prefer `GM_OK`/`GM_ERR_*`) and avoid mixing raw libgit2 error codes
Applied to files:
AGENTS.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/types.h : Define and consistently use the alias `typedef git_oid gm_oid_t` as the canonical OID type
Applied to files:
AGENTS.md
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to {include,core,src,apps}/**/*.h : Header guards must begin with GITMIND_ and remain stable
Applied to files:
AGENTS.mddocs/operations/Environment_Variables.md
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to include/{gitmind.h,gitmind/**/*.h} : Public headers must be umbrella-safe: compile standalone, maintain correct include order, have stable GITMIND_* header guards, and provide extern "C" when included from C++
Applied to files:
AGENTS.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/cache/*.{c,h} : Maintain consistent OID-centric naming for hash utilities and constants (e.g., `oid_hash()`, `OID_HASH_MULTIPLIER`)
Applied to files:
AGENTS.md
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: NEVER alter, disable, or otherwise circumvent git hooks or tests
Applied to files:
docs/operations/Environment_Variables.md
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to {include,core/include}/**/*.h : Header guards use GITMIND_* naming
Applied to files:
docs/operations/Environment_Variables.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/writer.c : Base64-encode CBOR payloads in commit messages to prevent binary corruption
Applied to files:
core/src/journal/writer.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/*.c : Do not hardcode CBOR field key magic numbers; use centralized definitions from `gitmind/cbor/keys.h`
Applied to files:
core/src/journal/writer.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/*.c : Add strict bounds checking for all CBOR parsing paths (lengths, indices, and buffer limits)
Applied to files:
core/src/journal/writer.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/meson.build : Do not hardcode `c_std=c23`; detect compiler support or provide a compatible minimum standard with feature checks
Applied to files:
meson.build
🧬 Code graph analysis (4)
core/tests/unit/test_journal_safety.c (1)
core/src/edge/edge.c (1)
gm_edge_equal(130-159)
core/src/util/ref.c (1)
core/include/gitmind/security/string.h (1)
gm_snprintf(74-80)
core/src/edge/edge.c (3)
core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)core/include/gitmind/util/memory.h (1)
gm_strcpy_safe(113-138)core/src/cbor/cbor.c (1)
gm_cbor_read_bytes(190-244)
core/src/journal/writer.c (2)
core/src/util/ref.c (1)
gm_build_ref(11-43)core/include/gitmind/security/memory.h (1)
gm_memcpy_safe(23-35)
🪛 GitHub Actions: Core Quality Checks
core/tests/unit/test_cache_query.c
[error] 67-67: use of undeclared identifier 'setenv'; did you mean 'getenv'? (Compiler: clang during ninja build; Command: clang -Itest_cache_query.p -I. -I.. -I../include -I../core/include -fdiagnostics-color=always -fsanitize=address -fno-omit-frame-pointer -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Wpedantic -Werror -std=c2x -O0 -g -ffreestanding -fstrict-flex-arrays=3 -Wdouble-promotion -Wpedantic -Wvla -Wshadow -Wstrict-prototypes -Wconversion -Wsign-conversion -Wfloat-equal -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -fno-common -fstrict-aliasing -DGITMIND_ENABLE_UTF8 -fsanitize=address -fno-omit-frame-pointer -g -pthread -MD -MQ test_cache_query.p/core_tests_unit_test_cache_query.c.o -MF test_cache_query.p/core_tests_unit_test_cache_query.c.o.d -o test_cache_query.p/core_tests_unit_test_cache_query.c.o -c ../core/tests/unit/test_cache_query.c)
[error] 67-67: too many arguments to function call, expected single argument '__name', have 3 arguments. (Compiler: clang during ninja build; Command: clang -Itest_cache_query.p -I. -I.. -I../include -I../core/include -fdiagnostics-color=always -fsanitize=address -fno-omit-frame-pointer -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -Wpedantic -Werror -std=c2x -O0 -g -ffreestanding -fstrict-flex-arrays=3 -Wdouble-promotion -Wpedantic -Wvla -Wshadow -Wstrict-prototypes -Wconversion -Wsign-conversion -Wfloat-equal -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -fno-common -fstrict-aliasing -DGITMIND_ENABLE_UTF8 -fsanitize=address -fno-omit-frame-pointer -g -pthread -MD -MQ test_cache_query.p/core_tests_unit_test_cache_query.c.o -MF test_cache_query.p/core_tests_unit_test_cache_query.c.o.d -o test_cache_query.p/core_tests_unit_test_cache_query.c.o -c ../core/tests/unit/test_cache_query.c)
meson.build
[warning] 368-368: WARNING: Trying to use ['address'] sanitizer on Clang with b_lundef. This will probably not work. Try setting b_lundef to false instead.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Compat Canaries (non-blocking) (gcc-12)
- GitHub Check: Compat Canaries (non-blocking) (clang-18)
- GitHub Check: Compat Canaries (non-blocking) (clang-19)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
🔇 Additional comments (16)
core/tests/unit/test_journal_safety.c (1)
72-76: Both-differ case is good and aligns with OID-first contract.core/tests/unit/test_cache_meta.c (2)
21-24: Confirm libgit2 API: git_treebuilder_new signature varies by version.Many libgit2 releases use git_treebuilder_new(&tb, source_tree) (no repo param). Verify CI image’s libgit2 matches this call or adjust accordingly.
Would you like me to grep headers in the CI image or check the pinned libgit2 version to ensure compatibility?
30-39: LGTM: commit-from-IDs + explicit legacy ref is clear.Direct commit creation and then git_reference_create to the legacy path simplifies the test and avoids ref side effects.
core/src/journal/writer.c (1)
185-196: LGTM: env-based branch override for tests.Simple, safe, and contained to tests; gm_build_ref will validate downstream.
docs/operations/Environment_Variables.md (3)
1-10: Front‑matter looks good.Metadata is complete and current.
32-36: Verified — default CI image matches workflows and local CI.
docs/operations/Environment_Variables.md defaultgitmind/ci:clang-20matches the fallbacks used in .github/workflows/c_core.yml and tools/ci/ci_local.sh.
82-87: Update docs: GITMIND_TEST_BRANCH is an unconditional test override when set — not only for repos without HEAD.core/src/journal/writer.c reads getenv("GITMIND_TEST_BRANCH") and prefers it over the current branch when non-empty (around line 185); update docs/operations/Environment_Variables.md to remove the "repo has no HEAD" qualification and state that the env var overrides the branch when set.
Likely an incorrect or invalid review comment.
meson.build (4)
126-127: LGTM:core/src/util/ref.cadded to sources.Matches the new
gm_build_refAPI usage elsewhere.
130-130: LGTM: include order favors public headers.This aligns with the constants unification work.
292-308: LGTM: new unit tests registered and linked correctly.Targets and deps look consistent.
332-335: LGTM: test registrations.No duplicates observed in this block.
core/src/edge/edge.c (5)
13-14: ✅ Good security hardening with memory safety headers.The addition of
gitmind/security/memory.handgitmind/util/memory.haligns with the PR's safety sweeps objective, providing safe memory operations to replace potentially vulnerable raw operations.
111-113: ✅ Proper safe string operations for path fields.Good use of
gm_strcpy_safewith appropriate bounds checking for both source and target paths, replacing potentially unsafe string operations.
337-348: ✅ Good OID-first CBOR encoding with safe fallback.The encoding correctly prefers OID fields while maintaining backward compatibility with SHA fallback when OIDs are unavailable. The cast to
const uint8_t*is appropriate for accessing raw OID bytes.
427-440: ✅ Proper CBOR decoding for new OID fields.The implementation correctly decodes the new OID fields from CBOR, using temporary buffers and
git_oid_fromrawto populate the edge's OID fields.
477-482: ✅ Appropriate OID backfill from legacy SHA.Good defensive programming - backfilling OIDs from legacy SHA fields when missing ensures consistent internal state after decoding older CBOR data.
| /* kept for reference; unused after env branch override */ | ||
| __attribute__((unused)) static void ensure_branch_with_commit(git_repository *repo, const char *branch) { | ||
| git_treebuilder *tb = NULL; | ||
| git_oid tree_oid, commit_oid; | ||
| git_signature *sig = NULL; | ||
| int rc; | ||
|
|
||
| rc = git_treebuilder_new(&tb, repo, NULL); | ||
| assert(rc == 0); | ||
| rc = git_treebuilder_write(&tree_oid, tb); | ||
| git_treebuilder_free(tb); | ||
| assert(rc == 0); | ||
|
|
||
| rc = git_signature_now(&sig, "tester", "tester@example.com"); | ||
| assert(rc == 0); | ||
|
|
||
| char refname[128]; | ||
| snprintf(refname, sizeof refname, "refs/heads/%s", branch); | ||
|
|
||
| git_tree *tree = NULL; | ||
| rc = git_tree_lookup(&tree, repo, &tree_oid); | ||
| assert(rc == 0); | ||
| rc = git_commit_create(&commit_oid, repo, refname, sig, sig, NULL, | ||
| "init", tree, 0, NULL); | ||
| git_tree_free(tree); | ||
| git_signature_free(sig); | ||
| assert(rc == 0); | ||
|
|
||
| rc = git_repository_set_head(repo, refname); | ||
| assert(rc == 0); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick
Drop the unused helper to keep tests lean.
Even with attribute((unused)), this dead code adds noise.
-/* kept for reference; unused after env branch override */
-__attribute__((unused)) static void ensure_branch_with_commit(git_repository *repo, const char *branch) {
- git_treebuilder *tb = NULL;
- git_oid tree_oid, commit_oid;
- git_signature *sig = NULL;
- int rc;
- rc = git_treebuilder_new(&tb, repo, NULL);
- assert(rc == 0);
- rc = git_treebuilder_write(&tree_oid, tb);
- git_treebuilder_free(tb);
- assert(rc == 0);
- rc = git_signature_now(&sig, "tester", "tester@example.com");
- assert(rc == 0);
- char refname[128];
- snprintf(refname, sizeof refname, "refs/heads/%s", branch);
- git_tree *tree = NULL;
- rc = git_tree_lookup(&tree, repo, &tree_oid);
- assert(rc == 0);
- rc = git_commit_create(&commit_oid, repo, refname, sig, sig, NULL,
- "init", tree, 0, NULL);
- git_tree_free(tree);
- git_signature_free(sig);
- assert(rc == 0);
- rc = git_repository_set_head(repo, refname);
- assert(rc == 0);
-}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /* kept for reference; unused after env branch override */ | |
| __attribute__((unused)) static void ensure_branch_with_commit(git_repository *repo, const char *branch) { | |
| git_treebuilder *tb = NULL; | |
| git_oid tree_oid, commit_oid; | |
| git_signature *sig = NULL; | |
| int rc; | |
| rc = git_treebuilder_new(&tb, repo, NULL); | |
| assert(rc == 0); | |
| rc = git_treebuilder_write(&tree_oid, tb); | |
| git_treebuilder_free(tb); | |
| assert(rc == 0); | |
| rc = git_signature_now(&sig, "tester", "tester@example.com"); | |
| assert(rc == 0); | |
| char refname[128]; | |
| snprintf(refname, sizeof refname, "refs/heads/%s", branch); | |
| git_tree *tree = NULL; | |
| rc = git_tree_lookup(&tree, repo, &tree_oid); | |
| assert(rc == 0); | |
| rc = git_commit_create(&commit_oid, repo, refname, sig, sig, NULL, | |
| "init", tree, 0, NULL); | |
| git_tree_free(tree); | |
| git_signature_free(sig); | |
| assert(rc == 0); | |
| rc = git_repository_set_head(repo, refname); | |
| assert(rc == 0); | |
| } |
🤖 Prompt for AI Agents
In core/tests/unit/test_cache_query.c around lines 16 to 46, the static helper
function ensure_branch_with_commit is unused and should be removed to reduce
dead code; delete the entire function definition (including the
__attribute__((unused)) declaration and its body) and ensure no remaining
references exist elsewhere in the file or tests; run the unit tests to confirm
no breakage.
| /* OIDs differ but legacy SHAs match => OID-first: not equal */ | ||
| gm_edge_t c = a, d = a; | ||
| uint8_t other_raw[GM_OID_RAWSZ]; | ||
| memset(other_raw, 0xBB, sizeof other_raw); | ||
| git_oid_fromraw(&c.src_oid, other_raw); | ||
| git_oid_fromraw(&d.tgt_oid, other_raw); | ||
| assert(gm_edge_equal(&c, &d)); | ||
| assert(!gm_edge_equal(&c, &d)); | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick
OID-first semantics correct; add src-only and tgt-only mismatch asserts for precision.
Current case changes both ends; add single-end deltas too.
git_oid_fromraw(&c.src_oid, other_raw);
git_oid_fromraw(&d.tgt_oid, other_raw);
assert(!gm_edge_equal(&c, &d));
+
+ /* Only source OID differs -> not equal */
+ gm_edge_t c2 = a, d2 = a;
+ git_oid_fromraw(&c2.src_oid, other_raw);
+ assert(!gm_edge_equal(&c2, &d2));
+
+ /* Only target OID differs -> not equal */
+ gm_edge_t c3 = a, d3 = a;
+ git_oid_fromraw(&d3.tgt_oid, other_raw);
+ assert(!gm_edge_equal(&c3, &d3));📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /* OIDs differ but legacy SHAs match => OID-first: not equal */ | |
| gm_edge_t c = a, d = a; | |
| uint8_t other_raw[GM_OID_RAWSZ]; | |
| memset(other_raw, 0xBB, sizeof other_raw); | |
| git_oid_fromraw(&c.src_oid, other_raw); | |
| git_oid_fromraw(&d.tgt_oid, other_raw); | |
| assert(gm_edge_equal(&c, &d)); | |
| assert(!gm_edge_equal(&c, &d)); | |
| /* OIDs differ but legacy SHAs match => OID-first: not equal */ | |
| gm_edge_t c = a, d = a; | |
| uint8_t other_raw[GM_OID_RAWSZ]; | |
| memset(other_raw, 0xBB, sizeof other_raw); | |
| git_oid_fromraw(&c.src_oid, other_raw); | |
| git_oid_fromraw(&d.tgt_oid, other_raw); | |
| assert(!gm_edge_equal(&c, &d)); | |
| /* Only source OID differs -> not equal */ | |
| gm_edge_t c2 = a, d2 = a; | |
| git_oid_fromraw(&c2.src_oid, other_raw); | |
| assert(!gm_edge_equal(&c2, &d2)); | |
| /* Only target OID differs -> not equal */ | |
| gm_edge_t c3 = a, d3 = a; | |
| git_oid_fromraw(&d3.tgt_oid, other_raw); | |
| assert(!gm_edge_equal(&c3, &d3)); |
🤖 Prompt for AI Agents
In core/tests/unit/test_journal_safety.c around lines 64 to 71, the test only
covers the case where both endpoints are changed; add two additional cases to
assert mismatches when only one endpoint differs: clone 'a' into a new gm_edge_t
(e.g., e), change only e.src_oid to other_raw and assert !gm_edge_equal(&e, &a);
then clone 'a' into another gm_edge_t (e.g., f), change only f.tgt_oid to
other_raw and assert !gm_edge_equal(&f, &a). Ensure you reuse the existing
other_raw and keep the same memset and git_oid_fromraw pattern so each
single-end delta is validated.
| - `GITMIND_CBOR_DEBUG` | ||
| - Purpose: Enable verbose CBOR decode tracing in the journal reader. | ||
| - Used by: `core/src/journal/reader.c`. | ||
| - Values: `1`, `true`, or `yes` (case-insensitive) to enable; anything else disables. | ||
| - Notes: Prints offsets and decode attempts to `stderr`; use only for debugging. | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick
Add an explicit “no CI/production” caution for CBOR debug.
This reduces accidental sensitive/verbose logging in shared environments.
Apply:
- - Notes: Prints offsets and decode attempts to `stderr`; use only for debugging.
+ - Notes: Prints offsets and decode attempts to `stderr`; use only for debugging. Avoid enabling in CI or production; logs may include decoded payload details.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - `GITMIND_CBOR_DEBUG` | |
| - Purpose: Enable verbose CBOR decode tracing in the journal reader. | |
| - Used by: `core/src/journal/reader.c`. | |
| - Values: `1`, `true`, or `yes` (case-insensitive) to enable; anything else disables. | |
| - Notes: Prints offsets and decode attempts to `stderr`; use only for debugging. | |
| - `GITMIND_CBOR_DEBUG` | |
| - Purpose: Enable verbose CBOR decode tracing in the journal reader. | |
| - Used by: `core/src/journal/reader.c`. | |
| - Values: `1`, `true`, or `yes` (case-insensitive) to enable; anything else disables. | |
| - Notes: Prints offsets and decode attempts to `stderr`; use only for debugging. Avoid enabling in CI or production; logs may include decoded payload details. | |
🤖 Prompt for AI Agents
In docs/operations/Environment_Variables.md around lines 45–50, add an explicit
caution directly after the "Notes" line warning that GITMIND_CBOR_DEBUG must not
be enabled in CI or production; state that it produces verbose output to stderr,
can expose sensitive data and overwhelm logs, and should only be used in
local/dev debugging sessions. Update the wording to be short and prescriptive
(e.g., "Do not enable in CI or production; local debugging only") and, if
desired, suggest using feature flags or guarded local-only scripts to set this
env var.
| project('git-mind', 'c', | ||
| version: '0.6.0', | ||
| default_options: ['c_std=c23', 'warning_level=3', 'werror=true']) | ||
| default_options: ['c_std=c2x', 'warning_level=3', 'werror=true']) | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick
ASAN + Clang warning: set b_lundef=false in sanitized builds.
CI shows “Trying to use ['address'] sanitizer on Clang with b_lundef…”. Pass -Db_lundef=false in the ASAN job (or create a dedicated sanitized configure step) to avoid link failures.
If desired, I can draft the workflow tweak for the sanitized job.
🤖 Prompt for AI Agents
In meson.build around lines 1 to 4, the CI sanitized build is failing on Clang
due to b_lundef being true; update the sanitized CI job to pass -Db_lundef=false
to meson configure (or add a dedicated sanitized configure step that includes
-Db_lundef=false) so the AddressSanitizer build on Clang links successfully.
|
Update:\n- Enforced Docker-only builds with Meson gate + warning blocks.\n- Finalized OID-first equality and aligned tests.\n- Hardened ref building for cross-libgit2 compatibility.\n- Stabilized cache_meta/cache_query tests for bare repos.\n- Local CI (Docker) is green: 24/24 tests pass.\n- Re-ran failing workflows (C-Core Gate, Core Quality Checks). Will monitor.\n\nIf any CI issue persists, I’ll patch swiftly to green. |
left a comment
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/tests/unit/test_cache_query.c (1)
1-107: Remove internal libgit2 <git2/sys/...> includesReplace the internal includes with public libgit2 headers (e.g. <git2/commit.h> or rely on <git2.h>) and remove these lines:
- core/tests/unit/test_cache_query.c:10 — #include <git2/sys/commit.h>
- core/tests/unit/test_cache_meta.c:8 — #include <git2/sys/commit.h>
♻️ Duplicate comments (1)
core/src/util/ref.c (1)
12-54: Build canonical refs via git_reference_normalize_name; remove ad‑hoc checks.Leverage libgit2 normalization, keep deterministic output, and map snprintf errors precisely. This also matches the PR’s stated behavior.
Apply:
int gm_build_ref(char *out, size_t out_sz, const char *prefix, const char *branch) { - if (!out || out_sz == 0 || !prefix || !branch) { - return GM_ERR_INVALID_ARGUMENT; - } - if (*branch == '\0') { - return GM_ERR_INVALID_ARGUMENT; - } - /* Require shorthand branch (no leading "refs/") to avoid double prefixing */ - if (branch[0] == 'r' && branch[1] == 'e' && branch[2] == 'f' && - branch[3] == 's' && branch[4] == '/') { - return GM_ERR_INVALID_ARGUMENT; - } - - char candidate[REF_NAME_BUFFER_SIZE]; - int rn = gm_snprintf(candidate, sizeof candidate, "%s%s", prefix, branch); - if (rn < 0 || (size_t)rn >= sizeof candidate) { - return GM_ERR_BUFFER_TOO_SMALL; - } - - /* Minimal validity checks without libgit2 dependency */ - { - const char *p = branch; - if (*p == '/' || p[strlen(p) - 1] == '/') { - return GM_ERR_INVALID_ARGUMENT; - } - for (; *p; ++p) { - const char c = *p; - if (c == '~' || c == '^' || c == ':' || c == '?' || - c == '[' || c == '*' || c == '\\') { - return GM_ERR_INVALID_ARGUMENT; - } - } - if (strstr(branch, "..") != NULL) return GM_ERR_INVALID_ARGUMENT; - if (strstr(branch, "@{") != NULL) return GM_ERR_INVALID_ARGUMENT; - } - - rn = gm_snprintf(out, out_sz, "%s", candidate); - if (rn < 0 || (size_t)rn >= out_sz) { - return GM_ERR_BUFFER_TOO_SMALL; - } - return GM_OK; + if (!out || out_sz == 0 || !prefix || !branch) return GM_ERR_INVALID_ARGUMENT; + out[0] = '\0'; + if (*branch == '\0') return GM_ERR_INVALID_ARGUMENT; + /* Require shorthand branch (no leading "refs/") to avoid double prefixing */ + if (strncmp(branch, "refs/", 5) == 0) return GM_ERR_INVALID_ARGUMENT; + + char candidate[REF_NAME_BUFFER_SIZE]; + int rn = gm_snprintf(candidate, sizeof candidate, "%s%s", prefix, branch); + if (rn < 0) return GM_ERR_INVALID_ARGUMENT; + if ((size_t)rn >= sizeof candidate) return GM_ERR_BUFFER_TOO_SMALL; + + char normalized[REF_NAME_BUFFER_SIZE]; + if (git_reference_normalize_name(normalized, sizeof normalized, candidate, 0) != 0) { + out[0] = '\0'; + return GM_ERR_INVALID_ARGUMENT; + } + + rn = gm_snprintf(out, out_sz, "%s", normalized); + if (rn < 0) { out[0] = '\0'; return GM_ERR_INVALID_ARGUMENT; } + if ((size_t)rn >= out_sz) { out[0] = '\0'; return GM_ERR_BUFFER_TOO_SMALL; } + return GM_OK; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
core/src/util/ref.c(1 hunks)core/tests/unit/test_cache_query.c(2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}
📄 CodeRabbit inference engine (CLAUDE.md)
NEVER use
NOLINTto suppress clang-tidy warnings; ALWAYS fix the underlying issue
Files:
core/tests/unit/test_cache_query.ccore/src/util/ref.c
core/**
📄 CodeRabbit inference engine (AGENTS.md)
Add new code under core/ (C23 library: include/ for public headers, src/ for implementation, tests/ for unit tests)
Files:
core/tests/unit/test_cache_query.ccore/src/util/ref.c
{core,src,apps,include}/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
{core,src,apps,include}/**/*.{c,h}: Use C23 with warnings-as-errors; forbid VLAs and variable shadowing; require explicit function prototypes
Follow .clang-format (LLVM-based, 4 spaces, 80 columns, pointer alignment right)
Function and variable names in lower_snake_case with gm_ prefix
Macro names in UPPER_SNAKE case
Type names end with _t
Prefer specific header includes; follow include ordering as enforced by .clang-format
Introduce no new clang-tidy warnings (lint via tools/docker-clang-tidy.sh)
Files:
core/tests/unit/test_cache_query.ccore/src/util/ref.c
core/tests/unit/test_*.c
📄 CodeRabbit inference engine (AGENTS.md)
Unit tests live in core/tests/unit/ and are named test_.c; keep tests deterministic and isolated
Files:
core/tests/unit/test_cache_query.c
core/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Files:
core/tests/unit/test_cache_query.ccore/src/util/ref.c
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
Applied to files:
core/tests/unit/test_cache_query.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/*.c : Use bounded string functions (e.g., `gm_snprintf`) and ensure explicit NUL termination on all string operations
Applied to files:
core/src/util/ref.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/**/*.c : Normalize error handling to a single scheme (prefer `GM_OK`/`GM_ERR_*`) and avoid mixing raw libgit2 error codes
Applied to files:
core/src/util/ref.c
🧬 Code graph analysis (1)
core/src/util/ref.c (1)
core/include/gitmind/security/string.h (1)
gm_snprintf(74-80)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Compat Canaries (non-blocking) (clang-19)
- GitHub Check: Compat Canaries (non-blocking) (clang-18)
- GitHub Check: Compat Canaries (non-blocking) (gcc-12)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
- GitHub Check: lint-and-sanitize
🔇 Additional comments (2)
core/tests/unit/test_cache_query.c (1)
67-67: LGTM: explicit test branch creation fixes prior env/setenv CI issue.This removes the need for env overrides and stabilizes the test.
core/src/util/ref.c (1)
10-11: Confirm git_reference_normalize_name availability in CI — gate or provide a fallback
- meson.build currently has libgit2_dep = dependency('libgit2', required : true) (≈line 79) and no code-level check for git_reference_normalize_name; either add a minimum libgit2 version requirement in meson.build or add a configure-time feature check (compile-time/cc.has_function) and a runtime/compile fallback.
- Verify the CI image (default IMAGE gitmind/ci:clang-20 in tools/ci/ci_local.sh) includes the libgit2 dev package with the required symbol.
| /* Require shorthand branch (no leading "refs/") to avoid double prefixing */ | ||
| if (branch[0] == 'r' && branch[1] == 'e' && branch[2] == 'f' && | ||
| branch[3] == 's' && branch[4] == '/') { | ||
| return GM_ERR_INVALID_ARGUMENT; | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick
Stale comment contradicts implementation.
“without libgit2 dependency” no longer applies after including <git2.h>. Remove or update.
🤖 Prompt for AI Agents
In core/src/util/ref.c around lines 20 to 24, the file comment that claims the
code is “without libgit2 dependency” is now stale because git2.h is included;
remove or update that comment to reflect that libgit2 is used (or reword to
explain why this check is independent of libgit2), and ensure the comment no
longer contradicts the current implementation.
| #include <git2.h> | ||
|
|
||
| #include "gitmind/cache.h" | ||
| #include <git2/sys/commit.h> |
There was a problem hiding this comment.
Avoid internal libgit2 headers; use public API.
Replace sys header with the public header (or drop entirely since <git2.h> is included).
Apply:
-#include <git2/sys/commit.h>
+#include <git2/commit.h>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| #include <git2/sys/commit.h> | |
| #include <git2/commit.h> |
🤖 Prompt for AI Agents
In core/tests/unit/test_cache_query.c at line 10, an internal header
<git2/sys/commit.h> is included; remove this internal sys header and either rely
on the already included public <git2.h> or, if you need commit-specific symbols,
include the public <git2/commit.h> instead.
| char refname[128]; | ||
| snprintf(refname, sizeof refname, "refs/heads/%s", branch); | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick
Minor: prefer gm_snprintf in core tests for consistency.
Not critical for tests, but aligns with repo’s safety wrappers.
Apply:
- snprintf(refname, sizeof refname, "refs/heads/%s", branch);
+ gm_snprintf(refname, sizeof refname, "refs/heads/%s", branch);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| char refname[128]; | |
| snprintf(refname, sizeof refname, "refs/heads/%s", branch); | |
| char refname[128]; | |
| gm_snprintf(refname, sizeof refname, "refs/heads/%s", branch); |
🤖 Prompt for AI Agents
In core/tests/unit/test_cache_query.c around lines 32 to 34, the test uses
snprintf to format refname; replace the call with the repository's safer wrapper
gm_snprintf using the same buffer and size arguments (gm_snprintf(refname,
sizeof refname, "refs/heads/%s", branch)) so tests follow the project's
consistency and safety conventions.
| /* Create a commit object and then a direct ref to it */ | ||
| rc = git_commit_create_from_ids(&commit_oid, repo, NULL, sig, sig, NULL, | ||
| "init", &tree_oid, 0, NULL); | ||
| git_signature_free(sig); | ||
| assert(rc == 0); | ||
| git_reference *ref = NULL; | ||
| rc = git_reference_create(&ref, repo, refname, &commit_oid, 1, "init"); | ||
| if (ref) git_reference_free(ref); | ||
| assert(rc == 0); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Use portable commit creation; drop dependency on commit-from-ids + manual ref create.
Prefer git_commit_create with a looked-up tree and update_ref=refname. This removes the need for internal headers and is widely supported.
Apply:
- /* Create a commit object and then a direct ref to it */
- rc = git_commit_create_from_ids(&commit_oid, repo, NULL, sig, sig, NULL,
- "init", &tree_oid, 0, NULL);
- git_signature_free(sig);
- assert(rc == 0);
- git_reference *ref = NULL;
- rc = git_reference_create(&ref, repo, refname, &commit_oid, 1, "init");
- if (ref) git_reference_free(ref);
- assert(rc == 0);
+ /* Create a commit at refname using the public API */
+ git_tree *tree = NULL;
+ rc = git_tree_lookup(&tree, repo, &tree_oid);
+ assert(rc == 0);
+ rc = git_commit_create(&commit_oid, repo, refname, sig, sig, NULL,
+ "init", tree, 0, NULL);
+ git_tree_free(tree);
+ git_signature_free(sig);
+ assert(rc == 0);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /* Create a commit object and then a direct ref to it */ | |
| rc = git_commit_create_from_ids(&commit_oid, repo, NULL, sig, sig, NULL, | |
| "init", &tree_oid, 0, NULL); | |
| git_signature_free(sig); | |
| assert(rc == 0); | |
| git_reference *ref = NULL; | |
| rc = git_reference_create(&ref, repo, refname, &commit_oid, 1, "init"); | |
| if (ref) git_reference_free(ref); | |
| assert(rc == 0); | |
| /* Create a commit at refname using the public API */ | |
| git_tree *tree = NULL; | |
| rc = git_tree_lookup(&tree, repo, &tree_oid); | |
| assert(rc == 0); | |
| rc = git_commit_create(&commit_oid, repo, refname, sig, sig, NULL, | |
| "init", tree, 0, NULL); | |
| git_tree_free(tree); | |
| git_signature_free(sig); | |
| assert(rc == 0); |
🤖 Prompt for AI Agents
In core/tests/unit/test_cache_query.c around lines 35 to 43, the test currently
builds a commit via git_commit_create_from_ids then manually creates a
reference; replace this with a portable git_commit_create call that looks up the
tree (git_tree_lookup or git_object_peel+lookup), passes the looked-up tree OID
into git_commit_create and uses the update_ref parameter set to refname so the
ref is created atomically; remove the manual git_reference_create call and
adjust cleanup to free the tree/commit signature objects as needed.
| rc = git_repository_set_head(repo, refname); | ||
| assert(rc == 0); | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick
Optional: set_head likely redundant after git_commit_create.
git_commit_create updates refname; HEAD is already pointing there when update_ref is used. Safe to keep, but can be removed.
🤖 Prompt for AI Agents
In core/tests/unit/test_cache_query.c around lines 45 to 47, the explicit call
to git_repository_set_head(repo, refname) is redundant because git_commit_create
already updates the ref (via update_ref) and HEAD will point there; remove the
git_repository_set_head call (or if you prefer to keep it for clarity, replace
it with a short comment stating it is optional/redundant) so the test relies on
the commit-created ref update and avoids unnecessary API calls.
…ds, cache meta ABI, branch length checks, path buffers, safe strcpy checks, include style); update review log
…ng fixes (ref zeroing, comments, front matter/headers/titles)
left a comment
There was a problem hiding this comment.
Actionable comments posted: 16
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
core/src/hooks/augment.c (2)
97-106: realloc growth: add overflow and OOM-safe handling.Double-check new_capacity overflow and use a temporary before assigning.
- size_t new_capacity = ctx->capacity * ARRAY_GROWTH_FACTOR; + size_t new_capacity = ctx->capacity * ARRAY_GROWTH_FACTOR; + if (new_capacity < ctx->capacity) { + return GM_ERR_OUT_OF_MEMORY; /* overflow */ + } gm_edge_t *new_edges = realloc(ctx->edges, new_capacity * sizeof(gm_edge_t)); if (!new_edges) { return GM_ERR_OUT_OF_MEMORY; }
215-239: Simplify merge detection.You can avoid git_repository_head() and use HEAD OID directly.
- /* Get HEAD */ - error = git_repository_head(&head_ref, repo); - if (error < 0) { - return GM_ERR_UNKNOWN; - } - - /* Get commit */ - git_oid oid; - error = git_reference_name_to_id(&oid, repo, "HEAD"); - git_reference_free(head_ref); + git_oid oid; + int error = git_reference_name_to_id(&oid, repo, "HEAD"); if (error < 0) { return GM_ERR_UNKNOWN; }core/src/cache/builder.c (2)
168-178: Check gm_snprintf results for path truncation.Propagate GM_ERR_BUFFER_TOO_SMALL if any path formatting truncates.
- (void)gm_snprintf(path, sizeof(path), "%s/%s", temp_dir, prefix); + int rn = gm_snprintf(path, sizeof(path), "%s/%s", temp_dir, prefix); + if (rn < 0 || (size_t)rn >= sizeof(path)) return GM_ERR_BUFFER_TOO_SMALL; (void)mkdir(path, DIR_PERMS_NORMAL); @@ - (void)gm_snprintf(path, sizeof(path), "%s/%s/%s.%s", temp_dir, - prefix, sha_hex, suffix); + rn = gm_snprintf(path, sizeof(path), "%s/%s/%s.%s", + temp_dir, prefix, sha_hex, suffix); + if (rn < 0 || (size_t)rn >= sizeof(path)) return GM_ERR_BUFFER_TOO_SMALL;
43-44: Unused constant.OID_HASH_MULTIPLIER is defined but unused; remove or use it in hashing.
♻️ Duplicate comments (6)
core/src/hooks/post-commit.c (2)
12-12: Public header switched to angle brackets — resolvedThis addresses the earlier note about using angle brackets for public headers. Looks good.
232-232: gm_memset_safe usage is correctCorrect 4‑arg signature and full-struct zeroing before field assignment. This resolves the prior compile/runtime concern.
core/src/hooks/augment.c (2)
58-58: Unify NOT_FOUND error code.Return GM_ERR_NOT_FOUND here to match other branches.
- return GM_NOT_FOUND; + return GM_ERR_NOT_FOUND;
7-7: Use angle brackets for public header include.Change quotes to angle brackets for public headers to follow include conventions.
-#include "gitmind/util/memory.h" +#include <gitmind/util/memory.h>core/src/cache/builder.c (2)
74-88: oid_hash: guard size==0 and use git_oid_raw().Prevent modulo by zero and use the public accessor for OID bytes.
/* Hash function for OID: lightweight mixing for better distribution */ static size_t oid_hash(const gm_oid_t *oid, size_t size) { - const uint8_t *raw = (const uint8_t *)oid->id; + if (size == 0) return 0; + const uint8_t *raw = (const uint8_t *)git_oid_raw(oid); uint32_t x = 0x9E3779B9u; /* golden ratio */ for (int i = 0; i < GM_OID_RAWSZ; i++) { x ^= raw[i]; x *= 0x85EBCA6Bu; /* mix */ x ^= (x >> 13); } /* final avalanche */ x ^= x >> 16; x *= 0x7FEB352Du; x ^= x >> 15; return (size_t)(x % (uint32_t)size); }
153-157: oid_to_hex: wrong size constant and return code.Use GM_OID_HEX_CHARS+1 (or GM_CACHE_OID_STRING_SIZE) and return GM_ERR_BUFFER_TOO_SMALL on insufficient buffer.
static int oid_to_hex(const gm_oid_t *oid, char *out, size_t out_size) { - if (out_size < SHA_HEX_SIZE) return GM_ERR_INVALID_ARGUMENT; + if (out_size < (GM_OID_HEX_CHARS + 1)) return GM_ERR_BUFFER_TOO_SMALL; (void)git_oid_tostr(out, out_size, oid); return GM_OK; }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (9)
.githooks/pre-push(1 hunks)core/include/gitmind/cache.h(7 hunks)core/include/gitmind/util/ref.h(1 hunks)core/src/cache/builder.c(12 hunks)core/src/hooks/augment.c(6 hunks)core/src/hooks/post-commit.c(2 hunks)docs/code-reviews/CLAUDE.md(2 hunks)docs/code-reviews/PR169/e4f3f906eb454cb103eb8cc6899df8dfbf6e2349.md(1 hunks)docs/templates/code-review-feedback.md(1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}
📄 CodeRabbit inference engine (CLAUDE.md)
NEVER use
NOLINTto suppress clang-tidy warnings; ALWAYS fix the underlying issue
Files:
core/include/gitmind/util/ref.hcore/src/hooks/post-commit.ccore/include/gitmind/cache.hcore/src/cache/builder.ccore/src/hooks/augment.c
core/**
📄 CodeRabbit inference engine (AGENTS.md)
Add new code under core/ (C23 library: include/ for public headers, src/ for implementation, tests/ for unit tests)
Files:
core/include/gitmind/util/ref.hcore/src/hooks/post-commit.ccore/include/gitmind/cache.hcore/src/cache/builder.ccore/src/hooks/augment.c
{core,src,apps,include}/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
{core,src,apps,include}/**/*.{c,h}: Use C23 with warnings-as-errors; forbid VLAs and variable shadowing; require explicit function prototypes
Follow .clang-format (LLVM-based, 4 spaces, 80 columns, pointer alignment right)
Function and variable names in lower_snake_case with gm_ prefix
Macro names in UPPER_SNAKE case
Type names end with _t
Prefer specific header includes; follow include ordering as enforced by .clang-format
Introduce no new clang-tidy warnings (lint via tools/docker-clang-tidy.sh)
Files:
core/include/gitmind/util/ref.hcore/src/hooks/post-commit.ccore/include/gitmind/cache.hcore/src/cache/builder.ccore/src/hooks/augment.c
{include,core,src,apps}/**/*.h
📄 CodeRabbit inference engine (AGENTS.md)
Header guards must begin with GITMIND_ and remain stable
Files:
core/include/gitmind/util/ref.hcore/include/gitmind/cache.h
core/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Files:
core/include/gitmind/util/ref.hcore/src/hooks/post-commit.ccore/include/gitmind/cache.hcore/src/cache/builder.ccore/src/hooks/augment.c
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Files:
docs/templates/code-review-feedback.mddocs/code-reviews/CLAUDE.mddocs/code-reviews/PR169/e4f3f906eb454cb103eb8cc6899df8dfbf6e2349.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Files:
docs/templates/code-review-feedback.mddocs/code-reviews/CLAUDE.mddocs/code-reviews/PR169/e4f3f906eb454cb103eb8cc6899df8dfbf6e2349.md
🧠 Learnings (22)
📓 Common learnings
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/hooks/augment.h : Public hook APIs should use the `gm_hook_` prefix; keep header guard stable to avoid breaking includes
Applied to files:
core/include/gitmind/util/ref.hcore/src/hooks/post-commit.ccore/src/hooks/augment.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h
Applied to files:
core/include/gitmind/util/ref.hcore/src/hooks/post-commit.ccore/include/gitmind/cache.hcore/src/cache/builder.ccore/src/hooks/augment.c
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to include/{gitmind.h,gitmind/**/*.h} : Public headers must be umbrella-safe: compile standalone, maintain correct include order, have stable GITMIND_* header guards, and provide extern "C" when included from C++
Applied to files:
core/include/gitmind/util/ref.hcore/src/hooks/post-commit.ccore/src/cache/builder.ccore/src/hooks/augment.c
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to {include,core,src,apps}/**/*.h : Header guards must begin with GITMIND_ and remain stable
Applied to files:
core/include/gitmind/util/ref.hcore/src/hooks/post-commit.ccore/src/cache/builder.ccore/src/hooks/augment.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to {include,core/include}/**/*.h : Header guards use GITMIND_* naming
Applied to files:
core/include/gitmind/util/ref.hcore/src/hooks/post-commit.ccore/src/cache/builder.ccore/src/hooks/augment.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/meson.build : Do not hardcode `c_std=c23`; detect compiler support or provide a compatible minimum standard with feature checks
Applied to files:
docs/code-reviews/CLAUDE.md
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: NEVER circumvent git hooks
Applied to files:
.githooks/pre-push
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to include/gitmind/**/*.h : Public, namespaced headers live under include/gitmind/
Applied to files:
core/src/hooks/post-commit.ccore/src/hooks/augment.c
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to include/gitmind/**/*.h : Place namespaced public headers under include/gitmind/
Applied to files:
core/src/hooks/post-commit.ccore/src/hooks/augment.c
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to {core,include}/**/*.{c,h} : Formatting: follow .clang-format (LLVM-based, 4 spaces, 80 cols, pointer alignment right); pre-commit enforces clang-format
Applied to files:
core/src/hooks/post-commit.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directly
Applied to files:
core/include/gitmind/cache.hcore/src/cache/builder.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/cache/*.{c,h} : Maintain consistent OID-centric naming for hash utilities and constants (e.g., `oid_hash()`, `OID_HASH_MULTIPLIER`)
Applied to files:
core/include/gitmind/cache.hcore/src/cache/builder.c
📚 Learning: 2025-09-15T01:21:16.867Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.867Z
Learning: Applies to core/**/*.{c,h} : Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Applied to files:
core/include/gitmind/cache.hcore/src/cache/builder.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/types.h : Define and consistently use the alias `typedef git_oid gm_oid_t` as the canonical OID type
Applied to files:
core/include/gitmind/cache.hcore/src/cache/builder.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/edge.h : Avoid struct bloat in `gm_edge_t`; do not store both legacy SHA arrays and OIDs long-term—phase out legacy SHA fields
Applied to files:
core/include/gitmind/cache.hcore/src/cache/builder.ccore/src/hooks/augment.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/reader.c : Split overly long CBOR decoder functions (e.g., `gm_edge_attributed_decode_cbor_ex`) into smaller units for maintainability
Applied to files:
core/include/gitmind/cache.h
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/journal/*.c : Add strict bounds checking for all CBOR parsing paths (lengths, indices, and buffer limits)
Applied to files:
core/src/cache/builder.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/edge/edge.c : When both OID and SHA are present, validate internal consistency (detect mismatches) rather than silently accepting either
Applied to files:
core/src/cache/builder.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/edge/edge.c : `gm_edge_equal()` must not use OR-style fallback; if OIDs are present use them exclusively, otherwise compare legacy fields—never consider objects equal when OIDs differ
Applied to files:
core/src/cache/builder.ccore/src/hooks/augment.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/*.c : Use bounded string functions (e.g., `gm_snprintf`) and ensure explicit NUL termination on all string operations
Applied to files:
core/src/cache/builder.c
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/hooks/augment.h : Remove or timebox deprecated compatibility macros rather than keeping them indefinitely
Applied to files:
core/src/hooks/augment.c
🧬 Code graph analysis (5)
core/include/gitmind/util/ref.h (1)
core/src/util/ref.c (1)
gm_build_ref(12-54)
core/src/hooks/post-commit.c (1)
core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)
core/include/gitmind/cache.h (2)
core/src/cache/builder.c (1)
gm_cache_rebuild(494-500)core/src/cache/query.c (5)
gm_cache_query_fanout(446-450)gm_cache_query_fanin(453-457)gm_cache_load_meta(97-169)gm_cache_is_stale(172-225)gm_cache_stats(471-516)
core/src/cache/builder.c (3)
core/src/util/ref.c (1)
gm_build_ref(12-54)core/include/gitmind/security/memory.h (1)
gm_memset_safe(47-59)core/include/gitmind/util/memory.h (1)
gm_strcpy_safe(113-138)
core/src/hooks/augment.c (1)
core/include/gitmind/util/memory.h (1)
gm_strcpy_safe(113-138)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Compat Canaries (non-blocking) (clang-18)
- GitHub Check: Compat Canaries (non-blocking) (clang-19)
- GitHub Check: Compat Canaries (non-blocking) (gcc-12)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
- GitHub Check: lint-and-sanitize
🔇 Additional comments (8)
docs/templates/code-review-feedback.md (1)
1-8: Front matter: quote placeholders; ensure it passes front‑matter checks.Quote dynamic placeholders to avoid YAML parsing surprises and confirm accepted values for status.
--- -title: {filename} -description: Preserved review artifacts and rationale. +title: "{filename}" +description: "Preserved review artifacts and rationale." audience: [contributors] domain: [quality] tags: [review] status: archive ---Verification: previous script failed with "check_docs.py: error: unrecognized arguments: --paths". Use positional paths instead — run:
#!/bin/bash # Front matter + docs checks for this file python3 tools/docs/check_docs.py --mode link docs/templates/code-review-feedback.md || exit 1 python3 tools/docs/check_docs.py --mode toc docs/templates/code-review-feedback.md || exit 1 # Lint (scoped if supported), else full: if make -n md-lint 2>/dev/null | grep -q md-lint; then make md-lint; fidocs/code-reviews/CLAUDE.md (1)
1-9: Front matter polish: align title with H1 and refresh last_updatedApply the diff below to docs/code-reviews/CLAUDE.md (lines 1–9). Validation couldn't be completed in the sandbox (make: command not found); re-run the doc lint/ToC/link checks locally or in CI.
--- -title: Code Review Notes +title: Code Review: migration/finish-core-cleanup Branch description: Code review guidelines and context. audience: [contributors] domain: [quality] tags: [review] status: archive -last_updated: 2025-09-15 +last_updated: 2025-09-16 ---core/src/hooks/augment.c (2)
154-158: Good: path truncation now fails.Checking gm_strcpy_safe and returning GM_ERR_BUFFER_TOO_SMALL is correct.
90-91: Incorrect — LOOKBACK_LIMIT is defined; no action needed.
core/include/gitmind/hooks/augment.h defines GM_AUGMENT_LOOKBACK_LIMIT and aliases LOOKBACK_LIMIT to it (see line 28), so the guard in core/src/hooks/augment.c is valid.Likely an incorrect or invalid review comment.
core/src/cache/builder.c (2)
496-497: Good input validation.Returning GM_ERR_INVALID_ARGUMENT for null ctx/repo/branch matches public API contracts.
389-393: Use gm_build_ref for stats too; avoid uninitialized ref_name on error.Replace manual snprintf with gm_build_ref and short-circuit on failure.
- char ref_name[REF_NAME_BUFFER_SIZE]; - { - int rn = gm_snprintf(ref_name, sizeof(ref_name), "%s%s", GM_CACHE_REF_PREFIX, branch); - if (rn < 0 || (size_t)rn >= sizeof(ref_name)) { - /* fall back to estimate below */ - rc = -1; - } - } + char ref_name[REF_NAME_BUFFER_SIZE]; + int brc = gm_build_ref(ref_name, sizeof(ref_name), GM_CACHE_REF_PREFIX, branch); + if (brc != GM_OK) { + rc = -1; /* fall back to estimate */ + } - git_oid cache_oid; - rc = git_reference_name_to_id(&cache_oid, repo, ref_name); + git_oid cache_oid; + if (rc == 0) { /* only attempt if ref_name is valid */ + rc = git_reference_name_to_id(&cache_oid, repo, ref_name); + }⛔ Skipped due to learnings
Learnt from: CR PR: neuroglyph/git-mind#0 File: docs/code-review/CLAUDE.md:0-0 Timestamp: 2025-09-15T01:19:37.384Z Learning: Applies to docs/code-review/core/src/{cache,edge}/*.c : Use `git_oid_cmp()` for OID equality and `git_oid_raw()` when byte-access is required; avoid `memcmp` on OIDs directlycore/include/gitmind/cache.h (2)
47-47: Deprecation tag looks good.Deprecated hex string retained; binary OID added at struct tail preserves ABI.
60-116: NODISCARD usage: LGTM.Annotating non-void APIs with GM_NODISCARD is appropriate for error-aware callers.
| while read -r local_ref local_sha remote_ref remote_sha; do | ||
| # Only enforce for pushes to main | ||
| if [[ "$remote_ref" == "refs/heads/main" ]]; then | ||
| # Determine the range to inspect | ||
| range="" | ||
| if [[ "$remote_sha" == "0000000000000000000000000000000000000000" ]]; then | ||
| # New branch/update; check last commit only | ||
| range="$local_sha^..$local_sha" | ||
| else | ||
| range="$remote_sha..$local_sha" | ||
| fi | ||
|
|
There was a problem hiding this comment.
Skip deletions to main.
If local_sha is all zeros (branch deletion), skip enforcement.
while read -r local_ref local_sha remote_ref remote_sha; do
# Only enforce for pushes to main
if [[ "$remote_ref" == "refs/heads/main" ]]; then
+ # Skip deletions
+ if [[ "$local_sha" == "0000000000000000000000000000000000000000" ]]; then
+ continue
+ fi📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| while read -r local_ref local_sha remote_ref remote_sha; do | |
| # Only enforce for pushes to main | |
| if [[ "$remote_ref" == "refs/heads/main" ]]; then | |
| # Determine the range to inspect | |
| range="" | |
| if [[ "$remote_sha" == "0000000000000000000000000000000000000000" ]]; then | |
| # New branch/update; check last commit only | |
| range="$local_sha^..$local_sha" | |
| else | |
| range="$remote_sha..$local_sha" | |
| fi | |
| while read -r local_ref local_sha remote_ref remote_sha; do | |
| # Only enforce for pushes to main | |
| if [[ "$remote_ref" == "refs/heads/main" ]]; then | |
| # Skip deletions | |
| if [[ "$local_sha" == "0000000000000000000000000000000000000000" ]]; then | |
| continue | |
| fi | |
| # Determine the range to inspect | |
| range="" | |
| if [[ "$remote_sha" == "0000000000000000000000000000000000000000" ]]; then | |
| # New branch/update; check last commit only | |
| range="$local_sha^..$local_sha" | |
| else | |
| range="$remote_sha..$local_sha" | |
| fi |
🤖 Prompt for AI Agents
.githooks/pre-push around lines 13 to 24: the hook treats a local_sha of all
zeros (branch deletion) as a new-branch case and proceeds to enforce checks
against main; detect when local_sha equals
0000000000000000000000000000000000000000 and skip enforcement by continuing the
loop (i.e., do not set a range or run checks for deletions to main), leaving
other logic unchanged.
| # New branch/update; check last commit only | ||
| range="$local_sha^..$local_sha" | ||
| else | ||
| range="$remote_sha..$local_sha" | ||
| fi | ||
|
|
There was a problem hiding this comment.
New-branch range: handle root commits safely.
Use diff-tree on the new commit instead of local^..local to avoid failures on root commits.
- range="$local_sha^..$local_sha"
+ range="$local_sha"
+ changelog_names="$(git diff-tree --no-commit-id --name-only -r "$local_sha")"
+ else
+ range="$remote_sha..$local_sha"
+ changelog_names="$(git diff --name-only "$range")"
- else
- range="$remote_sha..$local_sha"
- fi
+ fiThen test changelog_names instead of invoking git diff twice.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if [[ "$remote_sha" == "0000000000000000000000000000000000000000" ]]; then | |
| # New branch/update; check last commit only | |
| range="$local_sha^..$local_sha" | |
| else | |
| range="$remote_sha..$local_sha" | |
| fi | |
| if [[ "$remote_sha" == "0000000000000000000000000000000000000000" ]]; then | |
| # New branch/update; check last commit only | |
| range="$local_sha" | |
| changelog_names="$(git diff-tree --no-commit-id --name-only -r "$local_sha")" | |
| else | |
| range="$remote_sha..$local_sha" | |
| changelog_names="$(git diff --name-only "$range")" | |
| fi |
🤖 Prompt for AI Agents
In .githooks/pre-push around lines 18-23, the new-branch handling uses
"$local_sha^..$local_sha" which breaks for root commits and the script currently
invokes git diff twice; replace the new-branch range logic to obtain changed
files from the single new commit using git diff-tree (or equivalent
single-commit name-only listing) for "$local_sha" instead of using the caret
range, and then use that single result (changelog_names) for subsequent checks
rather than calling git diff a second time; ensure the existing-branch path
still uses the remote..local diff to populate changelog_names.
| if ! git diff --name-only "$range" | grep -iqE '(^|.*/)(CHANGELOG|CHANGES)(\.md)?$'; then | ||
| echo "[pre-push] No changelog file updated for push to main ($range)." >&2 | ||
| echo " Expected one of: CHANGELOG.md, CHANGES.md, or variants (case-insensitive)." >&2 | ||
| echo " Run: make changelog-add m=\"<one-liner>\"" >&2 | ||
| echo " Or bypass once: HOOKS_BYPASS=1 git push" >&2 | ||
| status=1 | ||
| fi | ||
| fi |
There was a problem hiding this comment.
🧹 Nitpick
Handle filenames with newlines; reuse computed names.
Use the already captured changelog_names and avoid a second git call; optionally use -z and map to newline if you later need robustness.
- if ! git diff --name-only "$range" | grep -iqE '(^|.*/)(CHANGELOG|CHANGES)(\.md)?$'; then
+ if ! printf '%s\n' "$changelog_names" | grep -iqE '(^|.*/)?(CHANGELOG|CHANGES)(\.md)?$'; then📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # Match common variants: CHANGELOG, CHANGES, with optional .md, case-insensitive, with or without paths | |
| if ! git diff --name-only "$range" | grep -iqE '(^|.*/)(CHANGELOG|CHANGES)(\.md)?$'; then | |
| echo "[pre-push] No changelog file updated for push to main ($range)." >&2 | |
| echo " Expected one of: CHANGELOG.md, CHANGES.md, or variants (case-insensitive)." >&2 | |
| echo " Run: make changelog-add m=\"<one-liner>\"" >&2 | |
| echo " Or bypass once: HOOKS_BYPASS=1 git push" >&2 | |
| status=1 | |
| fi | |
| # Match common variants: CHANGELOG, CHANGES, with optional .md, case-insensitive, with or without paths | |
| if ! printf '%s\n' "$changelog_names" | grep -iqE '(^|.*/)?(CHANGELOG|CHANGES)(\.md)?$'; then | |
| echo "[pre-push] No changelog file updated for push to main ($range)." >&2 | |
| echo " Expected one of: CHANGELOG.md, CHANGES.md, or variants (case-insensitive)." >&2 | |
| echo " Run: make changelog-add m=\"<one-liner>\"" >&2 | |
| echo " Or bypass once: HOOKS_BYPASS=1 git push" >&2 | |
| status=1 | |
| fi |
🤖 Prompt for AI Agents
.githooks/pre-push lines 26-33: the script is making a second git call and can
mis-handle filenames with newlines; reuse the already-captured changelog_names
variable instead of calling git diff again, and perform matching in a NUL-safe
way by using the NUL-separated names (git diff --name-only -z) or by printing
changelog_names with printf '%s\n' to feed grep; then run grep with the
appropriate flags (-z for NUL-separated input or regular grep for
newline-separated) and the same regex, set status=1 when no match, and avoid
invoking git twice.
| char branch[GM_CACHE_BRANCH_NAME_SIZE]; /**< Branch name (may be truncated if too long) */ | ||
| gm_oid_t journal_tip_oid_bin; /**< OID of last processed journal commit (preferred). Added at struct tail to preserve ABI layout. */ | ||
| } gm_cache_meta_t; |
There was a problem hiding this comment.
🧹 Nitpick
Branch field doc inconsistent with implementation.
Builder rejects long branch names; update comment to reflect “reject on overflow” instead of “may be truncated”.
- char branch[GM_CACHE_BRANCH_NAME_SIZE]; /**< Branch name (may be truncated if too long) */
+ char branch[GM_CACHE_BRANCH_NAME_SIZE]; /**< Branch name (rejected if >= limit; no truncation) */📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| char branch[GM_CACHE_BRANCH_NAME_SIZE]; /**< Branch name (may be truncated if too long) */ | |
| gm_oid_t journal_tip_oid_bin; /**< OID of last processed journal commit (preferred). Added at struct tail to preserve ABI layout. */ | |
| } gm_cache_meta_t; | |
| char branch[GM_CACHE_BRANCH_NAME_SIZE]; /**< Branch name (rejected if >= limit; no truncation) */ | |
| gm_oid_t journal_tip_oid_bin; /**< OID of last processed journal commit (preferred). Added at struct tail to preserve ABI layout. */ | |
| } gm_cache_meta_t; |
🤖 Prompt for AI Agents
In core/include/gitmind/cache.h around lines 52 to 54, the branch field comment
incorrectly says the branch "may be truncated if too long" while the
implementation/builder rejects names that overflow; update the comment to state
that branch names exceeding GM_CACHE_BRANCH_NAME_SIZE are rejected/causes an
error (no truncation) and reflect the actual behavior (e.g., "Branch name; names
longer than GM_CACHE_BRANCH_NAME_SIZE are rejected/validation fails") so the doc
matches implementation and ABI expectations.
| * Validation uses libgit2's git_reference_normalize_name on the combined ref. | ||
| * Returns GM_OK or error code. | ||
| */ |
There was a problem hiding this comment.
🧹 Nitpick
Doc mismatch with implementation (libgit2 normalization).
Header says validation uses git_reference_normalize_name, but implementation performs minimal local checks. Align the comment or update implementation.
- * Validation uses libgit2's git_reference_normalize_name on the combined ref.
+ * Validation performs minimal local checks; callers must treat return!=GM_OK
+ * as invalid and may optionally perform libgit2 normalization/lookup.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| * Validation uses libgit2's git_reference_normalize_name on the combined ref. | |
| * Returns GM_OK or error code. | |
| */ | |
| * Validation performs minimal local checks; callers must treat return!=GM_OK | |
| * as invalid and may optionally perform libgit2 normalization/lookup. | |
| * Returns GM_OK or error code. | |
| */ |
🤖 Prompt for AI Agents
core/include/gitmind/util/ref.h lines 17-19: the header claims validation uses
libgit2's git_reference_normalize_name but the implementation only does minimal
local checks; either update the comment to accurately describe the current
local-check behavior or change the implementation to call
git_reference_normalize_name on the combined ref and propagate libgit2 errors.
If you change the implementation, include the libgit2 header, build the combined
ref string as the comment describes, call git_reference_normalize_name, handle
NULL/err returns and translate them into the function's error codes, and add
unit tests; if you change the comment, rewrite the docstring to state that only
simple/local validation is performed and remove the reference to
git_reference_normalize_name.
…PR template, and docs-only label workflow
…references to tooling
…gets; add title/H1 checker; add manual workflow to seed review docs
left a comment
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (6)
docs/legacy/src/attribution.md (6)
11-14: Add a clear legacy disclaimer and pointer to current docSince this page is archived, add a short callout to steer readers to the current architecture doc. This also respects the Obsidian callout preference.
# Attribution System + +> [!WARNING]- +> Legacy/archived notes. Concepts here may differ from the current implementation. +> See: docs/architecture/attribution-system.md for up‑to‑date design and APIs.
34-44: Mark enum as legacy and cross‑reference unified constantsConstants were centralized in include/gitmind/constants.h. Flag this as a legacy sketch and link to the canonical header to avoid drift.
-```c +```c +/* Legacy sketch; see include/gitmind/constants.h for authoritative values/names */ typedef enum { GM_SOURCE_HUMAN = 0, /* Human-created edge */ GM_SOURCE_AI_CLAUDE = 1, /* Claude AI via MCP */ GM_SOURCE_AI_GPT = 2, /* GPT-4 or similar */ GM_SOURCE_AI_OTHER = 3, /* Other AI systems */ GM_SOURCE_SYSTEM = 4, /* System-generated (e.g., AUGMENTS) */ GM_SOURCE_IMPORT = 5, /* Imported from external source */ GM_SOURCE_UNKNOWN = 255 /* Unknown source */ } gm_source_type_t;Please also confirm enum names match current code (post “constants unification”). --- `56-62`: **Lane identifiers: verify against unified public constants** Ensure GM_LANE_* names reflect those in include/gitmind/constants.h after the unification; otherwise add a mapping note here. --- `92-102`: **Fenced block language + schema note** - Add a language to satisfy markdownlint fenced-code-language. - Consider noting the schema version and pointing to include/gitmind/cbor/constants_cbor.h. ```diff -``` +```text [ source_sha, tgt_sha, rel_type, confidence, timestamp, src_path, tgt_path, ulid, source_type, author, session_id, flags, lane // New fields ]
+Note: See include/gitmind/cbor/constants_cbor.h for field keys and schema/versioning.
--- `104-109`: **Env var naming inconsistent with repo convention** Elsewhere docs use GITMIND_* (e.g., GITMIND_CI_IMAGE). Here it’s GIT_MIND_*. Unify to avoid confusion, or explicitly document both if the code supports aliases. ```diff -- `GIT_MIND_SOURCE`: Set source type (human, claude, gpt, system) -- `GIT_MIND_AUTHOR`: Override author identification -- `GIT_MIND_SESSION`: Group edges in same session +- `GITMIND_SOURCE`: Set source type (human, claude, gpt, system) +- `GITMIND_AUTHOR`: Override author identification +- `GITMIND_SESSION`: Group edges in same sessionIf the code truly expects GIT_MIND_*, flip the diff accordingly and add a note in Environment_Variables.md.
110-121: Clarify accepted values/case and use neutral exampleDocument the accepted values and case-sensitivity for the SOURCE var and avoid vendor-specific addresses in examples.
-```bash -export GIT_MIND_SOURCE=claude -export GIT_MIND_AUTHOR=claude@anthropic -export GIT_MIND_SESSION=conv_abc123 -``` +```bash +# Accepted values: human | claude | gpt | system | other (case-insensitive? verify) +export GITMIND_SOURCE=claude +export GITMIND_AUTHOR=agent@example.com +export GITMIND_SESSION=conv_abc123 +```If aliases (e.g., GIT_MIND_* vs GITMIND_*) are supported, mention both explicitly.
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
docs/architecture/attribution-system.md(2 hunks)docs/features/Features_Ledger.md(1 hunks)docs/legacy/src/attribution.md(1 hunks)docs/legacy/src/edge.md(1 hunks)docs/legacy/src/sha.md(1 hunks)src/.gitignore(0 hunks)
💤 Files with no reviewable changes (1)
- src/.gitignore
✅ Files skipped from review due to trivial changes (2)
- docs/legacy/src/edge.md
- docs/legacy/src/sha.md
🚧 Files skipped from review as they are similar to previous changes (2)
- docs/architecture/attribution-system.md
- docs/features/Features_Ledger.md
🧰 Additional context used
📓 Path-based instructions (2)
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Files:
docs/legacy/src/attribution.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Files:
docs/legacy/src/attribution.md
🧠 Learnings (1)
📓 Common learnings
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Run build, tests, clang-tidy (via tools/docker-clang-tidy.sh), and gauntlet locally before proposing changes; keep changes zero-warnings and formatted
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/**/*.c : Normalize error handling to a single scheme (prefer `GM_OK`/`GM_ERR_*`) and avoid mixing raw libgit2 error codes
Learnt from: flyingrobots
PR: neuroglyph/git-mind#169
File: docs/templates/code-review-feedback.md:26-33
Timestamp: 2025-09-16T17:10:27.450Z
Learning: The user (flyingrobots) uses Obsidian to view/edit Markdown files and prefers to keep Obsidian-specific syntax like collapsible callout markers (e.g., `[!NOTE]-` for collapsible callouts) even if they're not GitHub-compatible.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Compat Canaries (non-blocking) (gcc-12)
- GitHub Check: Compat Canaries (non-blocking) (clang-19)
- GitHub Check: Compat Canaries (non-blocking) (clang-18)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
🔇 Additional comments (1)
docs/legacy/src/attribution.md (1)
1-9: Verify front-matter keys with docs checkerSandbox run failed (make not found); checks couldn't be executed. Run locally and confirm that status: archive (vs. archived) and the audience/domain arrays are accepted by tools/docs/check_docs.py.
Run locally:
- make md-lint
- python3 tools/docs/check_docs.py --mode link
- python3 tools/docs/check_docs.py --mode toc
- rg -n '^(status|audience|domain):' -C1 docs/ | sed -n '1,200p'
File: docs/legacy/src/attribution.md (lines 1-9)
left a comment
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/architecture/MODULAR_RESTRUCTURE_PLAN.md (1)
17-21: Fix TOC entries/anchors to match actual headings (will fail docs TOC check).Current TOC lists Goals/Plan/Milestones/Compatibility, which don’t exist. Replace with the real section headings.
Apply:
- - [Executive Summary](#executive-summary) - - [Goals](#goals) - - [Plan](#plan) - - [Milestones](#milestones) - - [Compatibility](#compatibility) + - [Executive Summary](#executive-summary) + - [Current Problems](#current-problems) + - [Proposed Architecture](#proposed-architecture) + - [Core Library Design](#core-library-design) + - [Migration Strategy ("3 Birds, 1 Stone")](#migration-strategy-3-birds-1-stone) + - [Quality Enforcement](#quality-enforcement) + - [File-by-File Migration Example](#file-by-file-migration-example) + - [Success Metrics](#success-metrics) + - [Backwards Compatibility](#backwards-compatibility) + - [Open Questions](#open-questions) + - [Next Steps](#next-steps)
♻️ Duplicate comments (1)
docs/cli/combined_markdown.md (1)
9-9: Aggregate flag present — thanks for closing the loop.This addresses the earlier suggestion to mark compiled pages.
🧹 Nitpick comments (16)
docs/tutorial.md (1)
44-46: Minor: separate command from output for readability.Use distinct fenced blocks (bash vs text) so linters and renderers don’t colorize output as shell.
-```bash -$ "$GIT_MIND" list --from README.md -README.md -> core/src/main.c (documents) -``` +```bash +$ "$GIT_MIND" list --from README.md +``` +```text +README.md -> core/src/main.c (documents) +```docs/architecture/MODULAR_RESTRUCTURE_PLAN.md (6)
65-75: Fix directory tree: avoid “core/src” under “core/”; move public header under top-level include/.Aligns with repo convention: public headers in include/gitmind/ (umbrella include/gitmind.h), sources in core/src.
Apply:
-│ ├── include/ -│ │ └── gitmind.h # THE single header (amalgamated) -│ ├── core/src/ # Source files (post-migration) +│ ├── src/ # Source files (post-migration) @@ -│ └── amalgamate.py # Combines sources into single header +│ └── amalgamate.py # Combines sources into single header +│ +├── include/ +│ └── gitmind.h # THE single header (amalgamated)
112-126: Single-header snippet: add extern "C" for C++ and avoid repo-internal .c paths.Use extern "C" in public headers and reference src/ paths to match the corrected tree (or note that amalgamation inlines sources).
Apply:
/* gitmind.h - Single header git-mind library */ #ifndef GITMIND_H #define GITMIND_H +#ifdef __cplusplus +extern "C" { +#endif + #ifdef GITMIND_IMPLEMENTATION /* Implementation details */ - #include "core/src/edge/edge.c" - #include "core/src/cbor/cbor.c" + /* In amalgamated builds these are inlined; paths shown for clarity */ + #include "src/edge/edge.c" + #include "src/cbor/cbor.c" /* ... */ #else /* Public API only */ /* ... declarations ... */ #endif - +#ifdef __cplusplus +} /* extern "C" */ +#endif #endif /* GITMIND_H */
96-96: Remove trailing spaces (markdownlint MD009).“- CBOR encoding/decoding␠␠” has two trailing spaces; they render as a hard line break.
-- CBOR encoding/decoding +- CBOR encoding/decoding
186-189: “Before Migration” path should reflect pre-move location.Use src/edge/edge.c (before), not core/src/edge/edge.c.
-// core/src/edge/edge.c +// src/edge/edge.c
3-11: Front matter looks good; consider adding a stable slug for link stability.Optional: add slug to avoid title‑derived anchor drift.
last_updated: 2025-09-15 --- +slug: modular-architecture-restructure-plan
232-245: Backwards-compat note: include path guidance should match umbrella include.Consider showing include <gitmind.h> explicitly to reinforce the new public API.
-- Old `#include "gitmind/*.h"` → `#include "gitmind.h"` +- Old `#include "gitmind/*.h"` → `#include <gitmind.h>`docs/wish-list-features/brain-storms/CLAUDE_ULTRATHINKS_GITMIND_FUTURE.md (3)
790-797: Swap real Ethereum address for a neutral placeholder in examples.Using a well-known live address can distract or imply endorsement. Prefer a dummy zero-address or clearly fake value.
-gm_contract_t *contract = gm_blockchain_connect( - "ethereum", - "0x742d35Cc6634C0532925a3b844Bc8e70387bEaE" -); +gm_contract_t *contract = gm_blockchain_connect( + "ethereum", + "0x0000000000000000000000000000000000000000" /* placeholder */ +);
1750-1791: Tone tweak for public docs (optional).If this file is user-facing, consider softening the final tagline to meet broad comms guidelines and markdown linters that flag profanity in headings/strong emphases.
-__LET'S MAKE GIT-MIND FUCKING LEGENDARY! 🚀__ +__LET'S MAKE GIT-MIND ABSOLUTELY LEGENDARY! 🚀__
49-56: Use OID-first gm_oid_t in docs exampleReplace the SHA-specific gm_sha1_t/commit_sha with gm_oid_t/commit_oid to align with the repo's OID-first policy (occurrence: docs/wish-list-features/brain-storms/CLAUDE_ULTRATHINKS_GITMIND_FUTURE.md: line 51).
- gm_sha1_t commit_sha; + gm_oid_t commit_oid;docs/cli/combined_markdown.md (3)
321-324: Normalize the “AUGMENTS” relation casing or document case-sensitivity.Examples mix
AUGMENTS(upper) andaugments(lower). If the CLI is case-sensitive, standardize and state the convention; if it’s case-insensitive, note that too to avoid user confusion.Also applies to: 642-644, 1017-1020
1099-1103: Note: example uses Bash process substitution.Readers on shells without process substitution may be confused. Add a one-liner note above the snippet.
### Test Coverage Discovery ```bash -# What files lack tests? +# What files lack tests? +# Note: requires Bash (process substitution). $ comm -23 \ <(git ls-files core/src/ | sort) \ <(git mind list --type tests --format tsv | cut -f2 | sort)--- `137-147`: **Cross-link ref naming/validation doc where refs are introduced.** When mentioning refs/gitmind/edges/<branch>, add a short parenthetical link to docs/architecture/Ref_Name_Validation.md for discoverability. </blockquote></details> <details> <summary>apps/cli/list.md (1)</summary><blockquote> `112-116`: **Globbing example: quoted pattern won’t expand in most shells** If the CLI expects the shell to expand globs, drop the quotes; if the CLI implements its own globbing, add a note saying quotes are intentional. ```diff -git-mind list "core/src/*.c" +git-mind list core/src/*.c +# If tool does its own globbing, keep quotes and add: +# (Pattern is parsed by git-mind; quotes prevent shell expansion.)docs/cli/gitmind-link.md (1)
10-10: Optional: bump last_updated to today if you touch the file again.If you apply the front‑matter move, consider updating last_updated to 2025-09-18.
docs/cli/gitmind-list.md (1)
8-8: Optional: refresh last_updated if more edits land.Consider setting last_updated to 2025-09-18 on next content change.
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (20)
README.md(10 hunks)apps/cli/list.md(5 hunks)docs/PRDs/PRD-co-thought-mcp-service.md(2 hunks)docs/TECHNICAL.md.md(1 hunks)docs/adult_swim.md(2 hunks)docs/api/gitmind-api-reference.md(3 hunks)docs/architecture/MODULAR_RESTRUCTURE_PLAN.md(4 hunks)docs/cli/combined_markdown.md(21 hunks)docs/cli/gitmind-cache-rebuild.md(3 hunks)docs/cli/gitmind-install-hooks.md(2 hunks)docs/cli/gitmind-link.md(6 hunks)docs/cli/gitmind-list.md(10 hunks)docs/cli/gitmind.md(4 hunks)docs/enforcer/gameplans/05-config-convention-overhaul.md(2 hunks)docs/enforcer/gameplans/09-domain-language-purity.md(3 hunks)docs/features/Features_Ledger.md(1 hunks)docs/quality/static-analysis-guide.md(2 hunks)docs/talk-shop/Graph-Lvl-Up-Tank.md(1 hunks)docs/tutorial.md(2 hunks)docs/wish-list-features/brain-storms/CLAUDE_ULTRATHINKS_GITMIND_FUTURE.md(1 hunks)
✅ Files skipped from review due to trivial changes (3)
- docs/TECHNICAL.md.md
- docs/api/gitmind-api-reference.md
- docs/adult_swim.md
🚧 Files skipped from review as they are similar to previous changes (10)
- docs/cli/gitmind-install-hooks.md
- docs/talk-shop/Graph-Lvl-Up-Tank.md
- docs/enforcer/gameplans/05-config-convention-overhaul.md
- docs/quality/static-analysis-guide.md
- docs/features/Features_Ledger.md
- docs/PRDs/PRD-co-thought-mcp-service.md
- docs/cli/gitmind.md
- docs/enforcer/gameplans/09-domain-language-purity.md
- docs/cli/gitmind-cache-rebuild.md
- README.md
🧰 Additional context used
📓 Path-based instructions (2)
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Files:
docs/tutorial.mddocs/wish-list-features/brain-storms/CLAUDE_ULTRATHINKS_GITMIND_FUTURE.mdapps/cli/list.mddocs/cli/gitmind-list.mddocs/cli/combined_markdown.mddocs/architecture/MODULAR_RESTRUCTURE_PLAN.mddocs/cli/gitmind-link.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Files:
docs/tutorial.mddocs/wish-list-features/brain-storms/CLAUDE_ULTRATHINKS_GITMIND_FUTURE.mddocs/cli/gitmind-list.mddocs/cli/combined_markdown.mddocs/architecture/MODULAR_RESTRUCTURE_PLAN.mddocs/cli/gitmind-link.md
🧠 Learnings (10)
📓 Common learnings
Learnt from: flyingrobots
PR: neuroglyph/git-mind#169
File: docs/templates/code-review-feedback.md:26-33
Timestamp: 2025-09-16T17:10:27.450Z
Learning: The user (flyingrobots) uses Obsidian to view/edit Markdown files and prefers to keep Obsidian-specific syntax like collapsible callout markers (e.g., `[!NOTE]-` for collapsible callouts) even if they're not GitHub-compatible.
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h
Applied to files:
apps/cli/list.mddocs/cli/gitmind-list.mddocs/cli/combined_markdown.mddocs/architecture/MODULAR_RESTRUCTURE_PLAN.md
📚 Learning: 2025-09-14T09:27:33.266Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.266Z
Learning: Tag all memories saved to MEMORY BANKS with at least #git-mind
Applied to files:
docs/cli/gitmind-list.md
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to {include,core,src,apps}/**/*.h : Header guards must begin with GITMIND_ and remain stable
Applied to files:
docs/cli/gitmind-list.mddocs/cli/combined_markdown.mddocs/architecture/MODULAR_RESTRUCTURE_PLAN.md
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to {include,core/include}/**/*.h : Header guards use GITMIND_* naming
Applied to files:
docs/cli/gitmind-list.mddocs/cli/combined_markdown.mddocs/architecture/MODULAR_RESTRUCTURE_PLAN.md
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to include/{gitmind.h,gitmind/**/*.h} : Public headers must be umbrella-safe: compile standalone, maintain correct include order, have stable GITMIND_* header guards, and provide extern "C" when included from C++
Applied to files:
docs/cli/gitmind-list.mddocs/cli/combined_markdown.mddocs/architecture/MODULAR_RESTRUCTURE_PLAN.md
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Applies to include/gitmind/**/*.h : Public, namespaced headers live under include/gitmind/
Applied to files:
docs/architecture/MODULAR_RESTRUCTURE_PLAN.md
📚 Learning: 2025-09-15T01:21:16.866Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-15T01:21:16.866Z
Learning: Applies to core/** : Add new code under core/ (C23 library: include/ for public headers, src/ for implementation, tests/ for unit tests)
Applied to files:
docs/architecture/MODULAR_RESTRUCTURE_PLAN.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/include/gitmind/edge.h : Avoid struct bloat in `gm_edge_t`; do not store both legacy SHA arrays and OIDs long-term—phase out legacy SHA fields
Applied to files:
docs/architecture/MODULAR_RESTRUCTURE_PLAN.md
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/edge/edge.c : `gm_edge_equal()` must not use OR-style fallback; if OIDs are present use them exclusively, otherwise compare legacy fields—never consider objects equal when OIDs differ
Applied to files:
docs/architecture/MODULAR_RESTRUCTURE_PLAN.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
🔇 Additional comments (8)
docs/tutorial.md (1)
33-35: Confirm 'documents' link type and example target existence
- Path update in docs/tutorial.md (example "Created: README.md -[documents]-> core/src/main.c") is fine.
- docs/cli/gitmind-link.md contains no reference to "documents" — confirm "documents" is a supported --type value and update the CLI docs if it is.
- core/src/main.c is not present in this checkout — ensure the example points to an in-repo file or clarify it's a built/generated path.
docs/architecture/MODULAR_RESTRUCTURE_PLAN.md (1)
15-21: Run docs TOC & link checks (use positional file args).check_docs.py takes file path(s) as positional args (not --files); CI may lack make — run:
python3 tools/docs/check_docs.py --mode toc docs/architecture/MODULAR_RESTRUCTURE_PLAN.md
python3 tools/docs/check_docs.py --mode link docs/architecture/MODULAR_RESTRUCTURE_PLAN.mddocs/cli/combined_markdown.md (1)
1-10: Front matter now precedes SPDX header — add license metadata and verify scanners.YAML front matter is fine, but some license scanners expect SPDX/license metadata at the top; add explicit fields and confirm scanner behavior.
File: docs/cli/combined_markdown.md (lines 1–10)
Apply this diff to enrich front matter (keeps HTML comments too):
--- title: README.md description: Combined CLI reference content for convenience and offline browsing. audience: [users, developers] domain: [cli] tags: [cli] status: draft last_updated: 2025-09-15 aggregate: true +license: LicenseRef-MIND-UCAL-1.0 +copyright: "© 2025 J. Kirby Ross / Neuroglyph Collective" ---Validation — I attempted to run the suggested checks but the sandbox failed with: "/bin/bash: line 3: make: command not found". Re-run these locally/CI and paste output if you want me to re-verify:
make md-lint python3 tools/docs/check_docs.py --mode link --paths docs/cli/combined_markdown.md python3 tools/docs/check_docs.py --mode toc --paths docs/cli/combined_markdown.md rg -nP '(?<!core/)src/' docs/cli/combined_markdown.md || trueapps/cli/list.md (2)
332-332: LGTM: path migration reflected in stats exampleThe switch to core/src/main.c is consistent with the rest of this doc.
210-211: Propagate include path fix across examplesReplace occurrences of include/api.h with the public umbrella header include/gitmind.h. Do not blindly replace include/parser.h with include/gitmind/parser.h — include/gitmind/parser.h is not present in this branch; either use include/gitmind.h or add the correct public parser header.
Affected locations: apps/cli/list.md (lines 40, 210, 217, 220, 224, 233–234, 339), docs/legacy/src/edge.md:175.
-IMPLEMENTS: core/src/main.c -> include/api.h +IMPLEMENTS: core/src/main.c -> include/gitmind.h -{"type":"implements","src":"core/src/main.c","tgt":"include/api.h",...} +{"type":"implements","src":"core/src/main.c","tgt":"include/gitmind.h",...} -implements,core/src/main.c,include/api.h,1.0,1720000000000 +implements,core/src/main.c,include/gitmind.h,1.0,1720000000000 - "core/src/main.c" -> "include/api.h" [label="implements"]; + "core/src/main.c" -> "include/gitmind.h" [label="implements"]; - core/src/main.c -> include/api.h + core/src/main.c -> include/gitmind.hdocs/cli/gitmind-list.md (2)
58-62: core/src path migration looks good across examples.The updated examples are coherent and match the repo-wide move.
Also applies to: 127-131, 138-152, 160-171, 178-199, 205-207, 230-233, 303-314, 330-330
1-9: Approve — front matter placement correct; docs checks passed.
check_frontmatter.py (--base docs) and check_docs.py (link, toc) on docs/cli/gitmind-list.md returned OK.docs/cli/gitmind-link.md (1)
47-49: Approve — path updates to core/src are consistent.
Examples were uniformly migrated from src/... to core/src/...; verified 20 occurrences in docs/cli/gitmind-link.md (lines 47–49, 90–97, 103–113, 119–122, 128–130, 135–137, 170–172, 215–219, 240–241).
| IMPLEMENTS: core/src/main.c -> include/api.h | ||
| REFERENCES: README.md -> docs/design.md | ||
| DEPENDS_ON: Makefile -> src/main.c | ||
| DEPENDS_ON: Makefile -> core/src/main.c | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
🧩 Analysis chain
Align include path with public headers layout
Examples still show include/api.h. Public headers live under include/gitmind/. Update example to avoid confusing users.
Apply:
-IMPLEMENTS: core/src/main.c -> include/api.h
+IMPLEMENTS: core/src/main.c -> include/gitmind.h🏁 Script executed:
#!/bin/bash
# Verify which public headers actually exist
fd -HI -t f '^api\.h$' include | sed 's/^/FOUND api.h: /' || true
fd -HI -t f '^gitmind\.h$' include | sed 's/^/FOUND gitmind.h: /' || trueLength of output: 34
Align include path with public headers layout
Examples still show include/api.h. Public headers live under include/gitmind/ — update example to avoid confusing users.
Apply:
-IMPLEMENTS: core/src/main.c -> include/api.h
+IMPLEMENTS: core/src/main.c -> include/gitmind.h📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| IMPLEMENTS: core/src/main.c -> include/api.h | |
| REFERENCES: README.md -> docs/design.md | |
| DEPENDS_ON: Makefile -> src/main.c | |
| DEPENDS_ON: Makefile -> core/src/main.c | |
| IMPLEMENTS: core/src/main.c -> include/gitmind.h | |
| REFERENCES: README.md -> docs/design.md | |
| DEPENDS_ON: Makefile -> core/src/main.c | |
🤖 Prompt for AI Agents
In apps/cli/list.md around lines 40 to 43, the example includes reference to
include/api.h which is incorrect given public headers live under
include/gitmind/; update the example lines to use the proper public header path
(e.g., include/gitmind/api.h) and scan the surrounding example block for any
other occurrences of include/api.h and replace them accordingly so documentation
matches the public headers layout.
| $ git mind link core/src/parser.c docs/parsing.md --type implements | ||
| $ git mind link core/src/lexer.c core/src/parser.c --type feeds | ||
| $ git mind cache-rebuild |
There was a problem hiding this comment.
🛠️ Refactor suggestion
🧩 Analysis chain
Path/ref alignment and CLI examples look consistent. Please run doc checks.
All updated paths use core/src and refs/gitmind/..., matching PR objectives.
Use this focused check to catch any stragglers and broken anchors:
Also applies to: 192-192, 476-478, 550-552, 594-600, 606-616, 621-625, 632-640, 718-722, 743-743, 846-850, 915-918, 926-930, 935-940, 949-951, 956-959, 966-970, 975-978, 984-987, 993-995, 1090-1090, 1101-1102, 1118-1118, 1291-1297, 1300-1302, 1308-1317, 1334-1336, 1347-1347
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Link + ToC checks (repository script)
python3 tools/docs/check_docs.py --mode link --paths docs/cli/combined_markdown.md
python3 tools/docs/check_docs.py --mode toc --paths docs/cli/combined_markdown.md
# Ensure examples consistently use 'git mind ' (space) form
rg -nP 'git-mind\s' docs/cli/combined_markdown.md || trueLength of output: 109
🏁 Script executed:
#!/bin/bash
set -uo pipefail
echo "=== Running docs/link check ==="
python3 tools/docs/check_docs.py --mode link docs/cli/combined_markdown.md || echo "check_docs.py --mode link exited with $?"
echo "=== Running docs/toc check ==="
python3 tools/docs/check_docs.py --mode toc docs/cli/combined_markdown.md || echo "check_docs.py --mode toc exited with $?"
echo "=== Searching for hyphenated 'git-mind' occurrences ==="
rg -nP 'git-mind\s' docs/cli/combined_markdown.md || echo "no 'git-mind ' matches"
echo "=== Searching for spaced 'git mind' occurrences ==="
rg -nP 'git mind\s' docs/cli/combined_markdown.md || echo "no 'git mind ' matches"
echo "=== Searching for 'core/src' occurrences ==="
rg -n 'core/src' docs/cli/combined_markdown.md || echo "no 'core/src' matches"
echo "=== Searching for 'refs/gitmind' occurrences ==="
rg -n 'refs/gitmind' docs/cli/combined_markdown.md || echo "no 'refs/gitmind' matches"Length of output: 13804
Docs link/toc OK — standardize CLI name to "git mind" (space)
check_docs.py --mode link/toc exited successfully. The file mixes hyphenated "git-mind" in TOC/section titles (e.g. lines 16, 38) with the spaced CLI form "git mind" in examples (e.g. lines 168, 178–180). Replace "git-mind" → "git mind" in headings/TOC and any CLI references for consistency.
🤖 Prompt for AI Agents
In docs/cli/combined_markdown.md around lines 178 to 180, headings/TOC and some
CLI references use the hyphenated form "git-mind" while examples use the spaced
form "git mind"; update all headings, TOC entries, and any CLI mentions to use
the standardized "git mind" (space) form so the document is consistent—search
the file for "git-mind" and replace with "git mind" in titles, TOC lines, and
inline CLI snippets, leaving other text unchanged.
| --- | ||
| title: git-mind link | ||
| description: Create a semantic connection between two paths. | ||
| audience: [users, developers] | ||
| domain: [cli] | ||
| tags: [cli, link] | ||
| status: stable | ||
| last_updated: 2025-09-15 | ||
| --- |
There was a problem hiding this comment.
🧩 Analysis chain
Move YAML front matter to the very top; place SPDX/copyright after it.
Front matter starts at Line 3 but is preceded by HTML comments on Lines 1–2. This violates the repo’s front‑matter rule and can fail docs/CI checks.
Apply this diff:
-<!-- SPDX-License-Identifier: LicenseRef-MIND-UCAL-1.0 -->
-<!-- © 2025 J. Kirby Ross / Neuroglyph Collective -->
---
title: git-mind link
description: Create a semantic connection between two paths.
audience: [users, developers]
domain: [cli]
tags: [cli, link]
status: stable
last_updated: 2025-09-15
---
+
+<!-- SPDX-License-Identifier: LicenseRef-MIND-UCAL-1.0 -->
+<!-- © 2025 J. Kirby Ross / Neuroglyph Collective -->Also applies to: 1-2
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 tools/docs/check_frontmatter.py docs/cli/gitmind-link.md
python3 tools/docs/check_docs.py --mode link --base docs
python3 tools/docs/check_docs.py --mode toc --base docsLength of output: 124
🏁 Script executed:
#!/bin/bash
set -euo pipefail
f="docs/cli/gitmind-link.md"
echo "== file head (first 30 lines) =="
nl -ba "$f" | sed -n '1,30p'
echo
echo "== lines containing only '---' (line numbers) =="
awk 'NR<=200{if($0=="---"){print NR}}' "$f" || true
echo
if [ -f tools/docs/check_frontmatter.py ]; then
echo "== running check_frontmatter.py --base docs =="
python3 tools/docs/check_frontmatter.py --base docs || true
else
echo "tools/docs/check_frontmatter.py not found"
fi
if [ -f tools/docs/check_docs.py ]; then
echo "== running check_docs.py link/toc =="
python3 tools/docs/check_docs.py --mode link --base docs || true
python3 tools/docs/check_docs.py --mode toc --base docs || true
else
echo "tools/docs/check_docs.py not found"
fiLength of output: 73
🏁 Script executed:
#!/bin/bash
set -euo pipefail
f="docs/cli/gitmind-link.md"
if [ ! -f "$f" ]; then
echo "MISSING: $f"
exit 0
fi
echo "== file exists: $f =="
wc -l "$f" || true
echo
echo "== lines 1-30 =="
sed -n '1,30p' "$f" || true
echo
echo "== lines starting with '<!--' (with numbers) =="
grep -n '^<!--' "$f" || true
echo
echo "== lines that are exactly '---' (with numbers) =="
grep -n '^---$' "$f" || true
echo
echo "== first 12 lines with visible EOL marker =="
sed -n '1,12p' "$f" | sed -e 's/$//' -e 's/^/→ /' || trueLength of output: 1405
Move YAML front matter to the very top; place SPDX/copyright after it.
Front matter opens at line 3 but is preceded by HTML comments on lines 1–2 — this violates the repo front‑matter rule and can fail docs CI.
File: docs/cli/gitmind-link.md — comments at lines 1–2; front matter opens at line 3 and closes at line 11.
-<!-- SPDX-License-Identifier: LicenseRef-MIND-UCAL-1.0 -->
-<!-- © 2025 J. Kirby Ross / Neuroglyph Collective -->
---
title: git-mind link
description: Create a semantic connection between two paths.
audience: [users, developers]
domain: [cli]
tags: [cli, link]
status: stable
last_updated: 2025-09-15
---
+
+<!-- SPDX-License-Identifier: LicenseRef-MIND-UCAL-1.0 -->
+<!-- © 2025 J. Kirby Ross / Neuroglyph Collective -->📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| --- | |
| title: git-mind link | |
| description: Create a semantic connection between two paths. | |
| audience: [users, developers] | |
| domain: [cli] | |
| tags: [cli, link] | |
| status: stable | |
| last_updated: 2025-09-15 | |
| --- | |
| --- | |
| title: git-mind link | |
| description: Create a semantic connection between two paths. | |
| audience: [users, developers] | |
| domain: [cli] | |
| tags: [cli, link] | |
| status: stable | |
| last_updated: 2025-09-15 | |
| --- | |
| <!-- SPDX-License-Identifier: LicenseRef-MIND-UCAL-1.0 --> | |
| <!-- © 2025 J. Kirby Ross / Neuroglyph Collective --> |
🤖 Prompt for AI Agents
In docs/cli/gitmind-link.md around lines 1 to 11, the YAML front matter
currently starts at line 3 but is preceded by HTML comments on lines 1–2 which
violates the repo rule; move the entire YAML block (lines 3–11) to the very top
of the file (starting at line 1), then place any SPDX/copyright or
license/copyright comments immediately after the closing --- of the front
matter, and remove or relocate the original HTML comments so no content precedes
the front matter.
| "core/src/auth.c", | ||
| GM_PREDICT_DEPENDENCIES | GM_PREDICT_IMPLEMENTS | ||
| ); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
🧩 Analysis chain
LGTM on path migration; please sweep remaining examples for consistency.
The change to "core/src/auth.c" matches the repo’s core/src move. Do a quick sweep in this doc (and optionally docs/) for stale "src/.c" examples to avoid mixed conventions. Consider a brief note up top that paths in snippets mirror the current repo layout.
🏁 Script executed:
#!/bin/bash
# Find stale path examples (should be core/src/* now)
rg -nP '\bsrc/[A-Za-z0-9_./-]+\.c\b' docs/wish-list-features/brain-storms/CLAUDE_ULTRATHINKS_GITMIND_FUTURE.md
# Optional: repo‑wide doc sweep for stale src/ paths (excluding core/src/)
rg -nP '\bsrc/(?!auth\.c|main\.c)[A-Za-z0-9_./-]+\.c\b' docsLength of output: 110
🏁 Script executed:
#!/bin/bash
# Show matches in the specific file
rg -n '\bsrc/[A-Za-z0-9_./-]+\.c\b' docs/wish-list-features/brain-storms/CLAUDE_ULTRATHINKS_GITMIND_FUTURE.md || true
# Repo-wide doc sweep for src/*.c examples (then filter out core/src/)
rg -n '\bsrc/[A-Za-z0-9_./-]+\.c\b' docs || true
rg -n '\bsrc/[A-Za-z0-9_./-]+\.c\b' docs | rg -v 'core/src/' || trueLength of output: 27238
Sweep docs for stale "src/*.c" paths — standardize on core/src/
Multiple docs still reference "src/…" (replace with "core/src/…") and add a one-line note that snippet paths mirror the current repo layout. Fix examples in (non‑exhaustive): docs/tutorial.md, docs/legacy/src/edge.md, docs/architecture/attribution-integration-guide.md, docs/enforcer/gameplans/03-observability-built-in.md, docs/enforcer/gameplans/04-testing-infrastructure-uplift.md, docs/cli/gitmind.md, docs/cli/gitmind-list.md, docs/operations/Environment_Variables.md, docs/architecture/MODULAR_RESTRUCTURE_PLAN.md.
🤖 Prompt for AI Agents
In docs/wish-list-features/brain-storms/CLAUDE_ULTRATHINKS_GITMIND_FUTURE.md
around lines 481-483, several documentation snippets reference "src/…" paths
that are now stale; update those references to "core/src/…" everywhere,
including the example files called out (docs/tutorial.md,
docs/legacy/src/edge.md, docs/architecture/attribution-integration-guide.md,
docs/enforcer/gameplans/03-observability-built-in.md,
docs/enforcer/gameplans/04-testing-infrastructure-uplift.md,
docs/cli/gitmind.md, docs/cli/gitmind-list.md,
docs/operations/Environment_Variables.md,
docs/architecture/MODULAR_RESTRUCTURE_PLAN.md), and add a one-line note in the
docs (near the top of docs or the examples section) stating that snippet paths
mirror the current repository layout so future moves should update paths
accordingly.
left a comment
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (3)
meson.build (3)
3-3: Don’t hardcode c_std; probe and select the best supported standard.Improves portability across toolchains and aligns with prior guidance.
- default_options: ['c_std=c2x', 'warning_level=3', 'werror=true']) + default_options: ['warning_level=3', 'werror=true'])Insert below the project() call:
cc = meson.get_compiler('c') std_candidates = ['-std=c2x', '-std=gnu2x', '-std=c23', '-std=gnu23'] std_supported = cc.get_supported_arguments(std_candidates) if std_supported.length() == 0 error('A C23-capable compiler is required (one of: c2x/gnu2x/c23/gnu23).') endif add_project_arguments(std_supported[0], language: 'c')
8-10: Avoid spawning shells to read env; use meson.get_env.Cheaper and more portable; preserves behavior.
-in_docker = run_command('sh', '-lc', '[ "$GITMIND_DOCKER" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' -in_ci = run_command('sh', '-lc', '[ -n "$GITHUB_ACTIONS" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' -env_override = run_command('sh', '-lc', '[ "$GITMIND_ALLOW_HOST_BUILD" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' +in_docker = meson.get_env('GITMIND_DOCKER') == '1' +in_ci = meson.get_env('GITHUB_ACTIONS') != '' +env_override = meson.get_env('GITMIND_ALLOW_HOST_BUILD') == '1'
377-377: Make -include header path robust for out-of-tree builds.Use join_paths with source_root to avoid '../' assumptions.
- c_args : ['-include', '../' + hdr], + c_args : ['-include', join_paths(meson.source_root(), hdr)],
🧹 Nitpick comments (6)
core/tests/unit/test_cache_tree_size.c (2)
29-31: Use a unique temp repo path (avoid collisions and filesystem residue).Hardcoding "./.gm_cache_tree_tmp" can clash across runs and leaves artifacts. Use mkdtemp (or a gm_* wrapper) and assert directory creation.
- git_repository *repo = NULL; - int rc = git_repository_init(&repo, "./.gm_cache_tree_tmp", true); + git_repository *repo = NULL; + char tmpdir[] = "/tmp/gm_cache_tree_XXXXXX"; + assert(mkdtemp(tmpdir) != NULL); + int rc = git_repository_init(&repo, tmpdir, true);Add (outside this hunk) at the top:
#include <stdlib.h>
76-81: Use uint64_t for expected to avoid width mismatch.Small, but keeps types aligned with total on 32/64-bit.
- size_t expected = 0; - expected += object_size(repo, &root_tree_oid); - expected += object_size(repo, &nested_tree_oid); - expected += object_size(repo, &root_blob_oid); - expected += object_size(repo, &nested_blob_oid); + uint64_t expected = 0; + expected += (uint64_t)object_size(repo, &root_tree_oid); + expected += (uint64_t)object_size(repo, &nested_tree_oid); + expected += (uint64_t)object_size(repo, &root_blob_oid); + expected += (uint64_t)object_size(repo, &nested_blob_oid);core/tests/unit/test_cache_branch_limits.c (3)
35-36: Bounds-check refname and prefer gm_snprintf + GM_PATH_MAX.Prevents silent truncation when branch names approach limits.
- char refname[256]; + char refname[GM_PATH_MAX]; @@ - snprintf(refname, sizeof refname, "refs/heads/%s", branch); + int n = gm_snprintf(refname, sizeof refname, "refs/heads/%s", branch); + assert(n > 0 && (size_t)n < sizeof refname);Add (outside this hunk) near includes:
#include "gitmind/constants.h" #include "gitmind/security/string.h"Also applies to: 47-47
67-69: Use a unique temp bare repo dir.Same rationale as the other test: avoid path collisions and leftovers.
- git_repository *repo = NULL; - int rc = git_repository_init(&repo, "./.gm_cache_branch_tmp", true); + git_repository *repo = NULL; + char tmpdir[] = "/tmp/gm_cache_branch_XXXXXX"; + assert(mkdtemp(tmpdir) != NULL); + int rc = git_repository_init(&repo, tmpdir, true);Add (outside this hunk) at the top if not present:
#include <stdlib.h>
92-93: Check ULID generation result.gm_ulid_generate returns a result; assert ok to catch unexpected failures.
- (void)gm_ulid_generate(edge.ulid); + gm_result_ulid_t ulr = gm_ulid_generate(edge.ulid); + assert(ulr.ok);docs/features/Features_Ledger.md (1)
156-156: Normalize status names to the canonical set.Use “v1.0.0” instead of “V1” to match the Status Model.
-| 🧰 | Safe String/Memory | Core | — | core/include/gitmind/util | v1.0.0 | 0.4 | V1 | 90% | █████████░ | Safe wrappers adopted in hot paths. | Sweep stragglers; docs. | Unit | Security uplift. | +| 🧰 | Safe String/Memory | Core | — | core/include/gitmind/util | v1.0.0 | 0.4 | v1.0.0 | 90% | █████████░ | Safe wrappers adopted in hot paths. | Sweep stragglers; docs. | Unit | Security uplift. |-| 🧪 | Worksheet Gates | DX | docs/tools | tools/review | Alpha | 0.3 | V1 | 90% | █████████░ | Pre‑push checks for placeholders + decisions. | Heuristics later (optional). | Scripted | Keeps quality high. | +| 🧪 | Worksheet Gates | DX | docs/tools | tools/review | Alpha | 0.3 | v1.0.0 | 90% | █████████░ | Pre‑push checks for placeholders + decisions. | Heuristics later (optional). | Scripted | Keeps quality high. |Also applies to: 179-179
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
core/tests/unit/test_cache_branch_limits.c(1 hunks)core/tests/unit/test_cache_tree_size.c(1 hunks)docs/features/Features_Ledger.md(1 hunks)meson.build(7 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}
📄 CodeRabbit inference engine (CLAUDE.md)
NEVER use
NOLINTto suppress clang-tidy warnings; ALWAYS fix the underlying issue
Files:
core/tests/unit/test_cache_tree_size.ccore/tests/unit/test_cache_branch_limits.c
core/**
📄 CodeRabbit inference engine (AGENTS.md)
Add new code under core/ (C23 library: include/ for public headers, src/ for implementation, tests/ for unit tests)
Files:
core/tests/unit/test_cache_tree_size.ccore/tests/unit/test_cache_branch_limits.c
{core,src,apps,include}/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
{core,src,apps,include}/**/*.{c,h}: Use C23 with warnings-as-errors; forbid VLAs and variable shadowing; require explicit function prototypes
Follow .clang-format (LLVM-based, 4 spaces, 80 columns, pointer alignment right)
Function and variable names in lower_snake_case with gm_ prefix
Macro names in UPPER_SNAKE case
Type names end with _t
Prefer specific header includes; follow include ordering as enforced by .clang-format
Introduce no new clang-tidy warnings (lint via tools/docker-clang-tidy.sh)
Files:
core/tests/unit/test_cache_tree_size.ccore/tests/unit/test_cache_branch_limits.c
core/tests/unit/test_*.c
📄 CodeRabbit inference engine (AGENTS.md)
Unit tests live in core/tests/unit/ and are named test_.c; keep tests deterministic and isolated
Files:
core/tests/unit/test_cache_tree_size.ccore/tests/unit/test_cache_branch_limits.c
core/**/*.{c,h}
📄 CodeRabbit inference engine (AGENTS.md)
Prefer OID-first APIs in new core code: use git_oid (typedef gm_oid_t) and compare via git_oid_cmp
Files:
core/tests/unit/test_cache_tree_size.ccore/tests/unit/test_cache_branch_limits.c
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Files:
docs/features/Features_Ledger.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Files:
docs/features/Features_Ledger.md
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/core/src/**/*.c : Normalize error handling to a single scheme (prefer `GM_OK`/`GM_ERR_*`) and avoid mixing raw libgit2 error codes
Learnt from: flyingrobots
PR: neuroglyph/git-mind#169
File: docs/templates/code-review-feedback.md:26-33
Timestamp: 2025-09-16T17:10:27.450Z
Learning: The user (flyingrobots) uses Obsidian to view/edit Markdown files and prefers to keep Obsidian-specific syntax like collapsible callout markers (e.g., `[!NOTE]-` for collapsible callouts) even if they're not GitHub-compatible.
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Use Meson/Ninja for build and tests; run lint and gauntlet locally; keep diffs minimal and pass CI with zero new clang-tidy warnings
Applied to files:
meson.build
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/meson.build : Do not hardcode `c_std=c23`; detect compiler support or provide a compatible minimum standard with feature checks
Applied to files:
meson.build
🧬 Code graph analysis (2)
core/tests/unit/test_cache_tree_size.c (1)
core/src/cache/tree_size.c (1)
gm_cache_calculate_size(89-93)
core/tests/unit/test_cache_branch_limits.c (3)
core/src/types/ulid.c (1)
gm_ulid_generate(118-126)core/src/journal/writer.c (1)
gm_journal_append(263-267)core/src/cache/builder.c (1)
gm_cache_rebuild(494-500)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Compat Canaries (non-blocking) (clang-18)
- GitHub Check: Compat Canaries (non-blocking) (gcc-12)
- GitHub Check: Compat Canaries (non-blocking) (clang-19)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
- GitHub Check: lint-and-sanitize
🔇 Additional comments (2)
core/tests/unit/test_cache_tree_size.c (1)
72-75: LGTM: good end-to-end check against ODB sizes.The test accurately validates gm_cache_calculate_size by summing tree+blob object sizes.
Also applies to: 82-88
docs/features/Features_Ledger.md (1)
58-62: Obsidian callouts retained intentionally.Good use of
[!INFO]-collapsible callouts per maintainer preference.Also applies to: 73-81, 92-97, 108-113
| #include <git2/sys/commit.h> | ||
|
|
There was a problem hiding this comment.
Avoid libgit2 internal APIs; replace git2/sys/commit.h and _from_ids with public API.
sys headers are unstable; use git_commit_create with a looked-up tree.
-#include <git2/sys/commit.h>
+/* use only public libgit2 API */
@@
- rc = git_commit_create_from_ids(&commit_oid, repo, NULL, sig, sig, NULL,
- "init", &tree_oid, 0, NULL);
+ git_tree *tree = NULL;
+ rc = git_tree_lookup(&tree, repo, &tree_oid);
+ assert(rc == 0 && tree);
+ rc = git_commit_create(&commit_oid, repo, NULL, sig, sig, NULL,
+ "init", tree, 0, NULL);
+ git_tree_free(tree);Also applies to: 48-51
🤖 Prompt for AI Agents
In core/tests/unit/test_cache_branch_limits.c around lines 9-10 (and also apply
same change at lines 48-51), the test is including the internal header
git2/sys/commit.h and calling internal _from_ids helpers; replace those usages
with public libgit2 API: remove the sys header include, use git_oid and public
lookup functions to obtain a git_tree (git_tree_lookup or
git_tree_lookup_prefix) and then create commits with git_commit_create (or
git_commit_create_v) passing the looked-up tree and parent OIDs; ensure error
handling and resource cleanup follow public API patterns.
| ${formula where features are weighted based on their estimated complexity}$ | ||
|
|
||
| And here's how we calculate the completion percentage of the overall project: | ||
|
|
||
| ${overall progress formula}$ | ||
|
|
There was a problem hiding this comment.
Replace placeholder formulas with concrete definitions (placeholders likely fail gates).
The ${…}$ placeholders will flag “placeholder” heuristics and are unclear. Provide real formulas or succinct prose.
Apply this diff:
-${formula where features are weighted based on their estimated complexity}$
+Milestone progress = Σ(weight_i × completion_i) / Σ(weight_i),
+where weight_i is each feature’s KLoC (or normalized complexity) within that milestone.
-${overall progress formula}$
+Overall progress = Σ(W_m × progress_m) / Σ(W_m),
+where W_m are milestone weights defined in the roadmap (e.g., MVP=1, Alpha=1, Beta=1, v1.0.0=2).📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ${formula where features are weighted based on their estimated complexity}$ | |
| And here's how we calculate the completion percentage of the overall project: | |
| ${overall progress formula}$ | |
| Milestone progress = Σ(weight_i × completion_i) / Σ(weight_i), | |
| where weight_i is each feature’s KLoC (or normalized complexity) within that milestone. | |
| And here's how we calculate the completion percentage of the overall project: | |
| Overall progress = Σ(W_m × progress_m) / Σ(W_m), | |
| where W_m are milestone weights defined in the roadmap (e.g., MVP=1, Alpha=1, Beta=1, v1.0.0=2). |
🤖 Prompt for AI Agents
In docs/features/Features_Ledger.md around lines 22 to 27, replace the two ${…}
placeholders with concrete formulas: define how feature weights are computed
from estimated complexity (e.g., weight_i = complexity_i /
sum_of_all_complexities) and define how a feature contributes to project
completion (e.g., feature_contribution = weight_i * feature_completion_percent),
then provide the overall progress formula as the sum of all feature
contributions (overall_progress = sum(feature_contribution_i)); keep the prose
short and include example variable names so readers can implement the formulas
unambiguously.
| **What “MVP” means:** Core linking/journal flows usable end-to-end for maintainers and early adopters; docs and safety rails in place for guided experiments. See `docs/planning/Milestone_Synthesis.md#mvpmmdash-show-hn-ready`. | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
🧩 Analysis chain
Fix likely-broken section anchors in links to Milestone_Synthesis.md.
The “-mdash-” tokens won’t match GitHub-style anchors. Use the canonical slugs.
Apply this diff:
-See `docs/planning/Milestone_Synthesis.md#mvpmmdash-show-hn-ready`.
+See `docs/planning/Milestone_Synthesis.md#mvp-show-hn-ready`.
-See `docs/planning/Milestone_Synthesis.md#alpha-mdash-team-productivity`.
+See `docs/planning/Milestone_Synthesis.md#alpha-team-productivity`.
-See `docs/planning/Milestone_Synthesis.md#beta-mdash-community-onboarding`.
+See `docs/planning/Milestone_Synthesis.md#beta-community-onboarding`.
-See `docs/planning/Milestone_Synthesis.md#v100-mdash-production-grade`.
+See `docs/planning/Milestone_Synthesis.md#v100-production-grade`.Run this to verify anchors and links locally:
Also applies to: 65-66, 84-85, 100-101
🏁 Script executed:
#!/bin/bash
set -euo pipefail
make md-lint || true
python3 tools/docs/check_docs.py --mode link docs/features/Features_Ledger.mdLength of output: 42
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "PWD: $(pwd)"
echo
echo "Checking docs directories..."
for d in docs docs/planning docs/features; do
if [ -d "$d" ]; then
echo "DIR: $d (exists)"
ls -la "$d" | sed -n '1,120p'
else
echo "DIR: $d (missing)"
fi
done
echo
for f in docs/features/Features_Ledger.md docs/planning/Milestone_Synthesis.md; do
if [ -f "$f" ]; then
echo "FOUND: $f"
else
echo "MISSING: $f"
fi
done
echo
echo "--- Lines in Features_Ledger.md containing 'Milestone_Synthesis.md' or 'mdash' ---"
if [ -f docs/features/Features_Ledger.md ]; then
grep -n -E 'Milestone_Synthesis.md#|mdash' docs/features/Features_Ledger.md || true
else
echo "Features_Ledger.md not found"
fi
echo
echo "--- Show first 220 lines of Features_Ledger.md ---"
if [ -f docs/features/Features_Ledger.md ]; then
sed -n '1,220p' docs/features/Features_Ledger.md | nl -ba | sed -n '1,220p'
else
echo "Features_Ledger.md not found"
fi
echo
echo "--- Headings in Milestone_Synthesis.md and computed GitHub-style slugs ---"
if [ -f docs/planning/Milestone_Synthesis.md ]; then
python3 - <<'PY'
import re, unicodedata, sys
p='docs/planning/Milestone_Synthesis.md'
try:
with open(p,'r',encoding='utf-8') as f:
lines=f.readlines()
except Exception as e:
print("ERROR reading",p, e)
sys.exit(0)
def slugify(s):
s = s.strip().lower()
s = unicodedata.normalize('NFKD', s)
s = re.sub(r'<.*?>', '', s)
s = re.sub(r'[^a-z0-9\s-]', ' ', s)
s = re.sub(r'\s+', '-', s)
s = re.sub(r'-+', '-', s)
s = s.strip('-')
return s
for i,l in enumerate(lines, start=1):
m=re.match(r'^(#{1,6})\s+(.*)', l)
if m:
level=len(m.group(1))
title=m.group(2).strip()
print(f"{i:4d} H{level} {title} -> #{slugify(title)}")
PY
else
echo "Milestone_Synthesis.md not found"
fi
echo
echo "--- Search for exact anchors suggested in the diff ---"
if [ -f docs/planning/Milestone_Synthesis.md ]; then
for a in "#mvp-show-hn-ready" "#alpha-team-productivity" "#beta-community-onboarding" "#v100-production-grade"; do
echo "Searching for anchor: $a"
grep -n "${a#\#}" docs/planning/Milestone_Synthesis.md || true
done
fiLength of output: 4195
🏁 Script executed:
#!/bin/bash
set -euo pipefail
MS="docs/planning/Milestone_Synthesis.md"
FL="docs/features/Features_Ledger.md"
if [ ! -f "$MS" ]; then
echo "Milestone_Synthesis.md not found: $MS"
exit 0
fi
if [ ! -f "$FL" ]; then
echo "Features_Ledger.md not found: $FL"
exit 0
fi
echo "=== Headings in $MS with computed GitHub-style slugs ==="
python3 - <<'PY'
import re, unicodedata
p='docs/planning/Milestone_Synthesis.md'
def slugify(s):
s = s.strip().lower()
s = unicodedata.normalize('NFKD', s)
s = re.sub(r'<.*?>', '', s)
s = re.sub(r'[^a-z0-9\s-]', ' ', s)
s = re.sub(r'\s+', '-', s)
s = re.sub(r'-+', '-', s)
return s.strip('-')
with open(p, 'r', encoding='utf-8') as f:
for i, line in enumerate(f, start=1):
m = re.match(r'^(#{1,6})\s+(.*)', line)
if m:
title = m.group(2).strip()
print(f"{i:4d} {title} -> #{slugify(title)}")
PY
echo
echo "=== Problematic anchor occurrences in $FL ==="
grep -n -E 'Milestone_Synthesis.md#.*mdash|Milestone_Synthesis.md#mvpmmdash|Milestone_Synthesis.md#alpha-mdash|Milestone_Synthesis.md#beta-mdash|Milestone_Synthesis.md#v100-mdash' "$FL" || true
echo
echo "=== Suggestion (apply these replacements) ==="
cat <<'EOF'
See `docs/planning/Milestone_Synthesis.md#mvpmmdash-show-hn-ready`.
=> See `docs/planning/Milestone_Synthesis.md#mvp-show-hn-ready`.
See `docs/planning/Milestone_Synthesis.md#alpha-mdash-team-productivity`.
=> See `docs/planning/Milestone_Synthesis.md#alpha-team-productivity`.
See `docs/planning/Milestone_Synthesis.md#beta-mdash-community-onboarding`.
=> See `docs/planning/Milestone_Synthesis.md#beta-community-onboarding`.
See `docs/planning/Milestone_Synthesis.md#v100-mdash-production-grade`.
=> See `docs/planning/Milestone_Synthesis.md#v100-production-grade`.
EOFLength of output: 2165
Fix Milestone_Synthesis.md anchors in Features_Ledger.md.
Replace occurrences in docs/features/Features_Ledger.md:
- Line 50:
docs/planning/Milestone_Synthesis.md#mvpmmdash-show-hn-ready→docs/planning/Milestone_Synthesis.md#mvp-show-hn-ready - Line 65:
docs/planning/Milestone_Synthesis.md#alpha-mdash-team-productivity→docs/planning/Milestone_Synthesis.md#alpha-team-productivity - Line 84:
docs/planning/Milestone_Synthesis.md#beta-mdash-community-onboarding→docs/planning/Milestone_Synthesis.md#beta-community-onboarding - Line 100:
docs/planning/Milestone_Synthesis.md#v100-mdash-production-grade→docs/planning/Milestone_Synthesis.md#v1-0-0-production-grade
🤖 Prompt for AI Agents
In docs/features/Features_Ledger.md around lines 50-100, several broken anchor
links to docs/planning/Milestone_Synthesis.md must be corrected: change the
anchor at line 50 from
docs/planning/Milestone_Synthesis.md#mvpmmdash-show-hn-ready to
docs/planning/Milestone_Synthesis.md#mvp-show-hn-ready; at line 65 change
docs/planning/Milestone_Synthesis.md#alpha-mdash-team-productivity to
docs/planning/Milestone_Synthesis.md#alpha-team-productivity; at line 84 change
docs/planning/Milestone_Synthesis.md#beta-mdash-community-onboarding to
docs/planning/Milestone_Synthesis.md#beta-community-onboarding; and at line 100
change docs/planning/Milestone_Synthesis.md#v100-mdash-production-grade to
docs/planning/Milestone_Synthesis.md#v1-0-0-production-grade so each link
matches the actual anchor names.
c032894 to
7b894b1
Compare
left a comment
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (4)
meson.build (4)
3-3: Don’t hardcode C standard; probe and select highest supported (C23/2x).Keeps older toolchains working and aligns with prior guidance.
-project('git-mind', 'c', - version: '0.6.0', - default_options: ['c_std=c2x', 'warning_level=3', 'werror=true']) +project('git-mind', 'c', + version: '0.6.0', + default_options: ['warning_level=3', 'werror=true']) + +# Select the highest supported C23/2x mode +cc = meson.get_compiler('c') +std_candidates = ['-std=c2x', '-std=gnu2x', '-std=c23', '-std=gnu23'] +std_supported = cc.get_supported_arguments(std_candidates) +if std_supported.length() == 0 + error('A C23-capable compiler is required (supports one of: c2x/gnu2x/c23/gnu23).') +endif +add_project_arguments(std_supported[0], language: 'c')
8-12: Avoid subshells for env reads; use meson.get_env().Cheaper, clearer, and more portable.
-in_docker = run_command('sh', '-lc', '[ "$GITMIND_DOCKER" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' -in_ci = run_command('sh', '-lc', '[ -n "$GITHUB_ACTIONS" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' -env_override = run_command('sh', '-lc', '[ "$GITMIND_ALLOW_HOST_BUILD" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' +in_docker = meson.get_env('GITMIND_DOCKER') == '1' +in_ci = meson.get_env('GITHUB_ACTIONS') != '' +env_override = meson.get_env('GITMIND_ALLOW_HOST_BUILD') == '1'
343-348: Duplicate test registrations resolved.Now registered once each; configure error avoided.
377-378: Make -include path robust for out-of-tree builds.Avoid '../' assumptions; use source-root absolute path.
- c_args : ['-include', '../' + hdr], + c_args : ['-include', join_paths(meson.source_root(), hdr)],
🧹 Nitpick comments (1)
meson.build (1)
166-166: DRY up repeated test dependencies.Define once and reuse to reduce churn.
# Dependencies libsodium_dep = dependency('libsodium', required : true) libgit2_dep = dependency('libgit2', required : true) thread_dep = dependency('threads') +test_deps_common = [libsodium_dep, libgit2_dep, thread_dep] … -test_error = executable('test_error', +test_error = executable('test_error', 'core/tests/unit/test_error.c', include_directories : inc, link_with : libgitmind, - dependencies : [libsodium_dep, libgit2_dep, thread_dep]) + dependencies : test_deps_common) … - dependencies : [libsodium_dep, libgit2_dep, thread_dep]) + dependencies : test_deps_common)Apply the same replacement to the other test executables shown in the selected lines. Leave tests that intentionally differ (those using test_backend_lib with custom deps) as-is.
Also applies to: 172-172, 178-178, 184-184, 190-190, 210-210, 216-216, 223-223, 230-230, 236-236, 242-242, 248-248, 254-254, 260-260, 266-266, 272-272, 278-278, 284-284, 290-290, 296-296, 302-302, 308-308, 314-314, 319-319
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
core/tests/unit/test_cache_branch_limits.c(1 hunks)core/tests/unit/test_cache_tree_size.c(1 hunks)docs/features/Features_Ledger.md(1 hunks)meson.build(7 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- core/tests/unit/test_cache_branch_limits.c
- core/tests/unit/test_cache_tree_size.c
- docs/features/Features_Ledger.md
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: flyingrobots
PR: neuroglyph/git-mind#169
File: docs/templates/code-review-feedback.md:26-33
Timestamp: 2025-09-16T17:10:27.450Z
Learning: The user (flyingrobots) uses Obsidian to view/edit Markdown files and prefers to keep Obsidian-specific syntax like collapsible callout markers (e.g., `[!NOTE]-` for collapsible callouts) even if they're not GitHub-compatible.
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Use Meson/Ninja for build and tests; run lint and gauntlet locally; keep diffs minimal and pass CI with zero new clang-tidy warnings
Applied to files:
meson.build
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/meson.build : Do not hardcode `c_std=c23`; detect compiler support or provide a compatible minimum standard with feature checks
Applied to files:
meson.build
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Compat Canaries (non-blocking) (clang-19)
- GitHub Check: Compat Canaries (non-blocking) (gcc-12)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
- GitHub Check: Compat Canaries (non-blocking) (clang-18)
🔇 Additional comments (5)
meson.build (5)
5-5: Docs pointer LGTM.Good move to meson_options.txt.
13-32: Host-build hard gate: sensible with override path.Message is clear; guard matches PR policy.
Please confirm CI images export GITMIND_DOCKER=1 everywhere (including sanitized/clang-tidy jobs) to avoid accidental gate trips.
126-127: New util/ref wired into lib.Matches tests/docs; good.
130-130: Include order change LGTM.Public first helps avoid accidental shadowing.
286-291: New tests added and linked correctly.Targets + deps look consistent; nice coverage expansion.
Also applies to: 298-303, 304-309, 310-320
7b894b1 to
62c7e48
Compare
left a comment
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (3)
meson.build (3)
3-3: Don’t hardcode c_std; detect highest supported (per prior preference).Replace the fixed
c_std=c2xwith compiler-probed flags and require a C23-capable mode.-project('git-mind', 'c', - version: '0.6.0', - default_options: ['c_std=c2x', 'warning_level=3', 'werror=true']) +project('git-mind', 'c', + version: '0.6.0', + default_options: ['warning_level=3', 'werror=true']) + +cc = meson.get_compiler('c') +std_candidates = ['-std=c2x', '-std=gnu2x', '-std=c23', '-std=gnu23'] +std_supported = cc.get_supported_arguments(std_candidates) +if std_supported.length() == 0 + error('A C23-capable compiler is required (supports one of: c2x/gnu2x/c23/gnu23).') +endif +add_project_arguments(std_supported[0], language: 'c')
8-12: Stop spawning shells for env checks; use meson.get_env().Cheaper, portable, and clearer.
-in_docker = run_command('sh', '-lc', '[ "$GITMIND_DOCKER" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' -in_ci = run_command('sh', '-lc', '[ -n "$GITHUB_ACTIONS" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' -env_override = run_command('sh', '-lc', '[ "$GITMIND_ALLOW_HOST_BUILD" = "1" ] && echo 1 || echo 0', check: false).stdout().strip() == '1' +in_docker = meson.get_env('GITMIND_DOCKER') == '1' +in_ci = meson.get_env('GITHUB_ACTIONS') != '' +env_override = meson.get_env('GITMIND_ALLOW_HOST_BUILD') == '1'
377-377: Make -include path robust for out-of-tree builds.Use source_root + join_paths instead of
../.- c_args : ['-include', '../' + hdr], + c_args : ['-include', join_paths(meson.source_root(), hdr)],
🧹 Nitpick comments (6)
meson.build (6)
37-37: Avoid global -ffreestanding; scope it to the library only.Global freestanding can break tests and sanitizers; apply only to lib.
- '-ffreestanding', # library and want tight control
142-149: Apply -ffreestanding only to libgitmind.Move the flag here (paired with the removal above).
libgitmind = static_library( 'gitmind', src, include_directories : inc, - dependencies : [libsodium_dep, libgit2_dep, thread_dep, roaring_dep], - c_args : roaring_inc_args + dependencies : [libsodium_dep, libgit2_dep, thread_dep, roaring_dep], + c_args : roaring_inc_args + ['-ffreestanding'] )
38-39: Gate -fstrict-flex-arrays=3 by compiler support.Older compilers may not accept
=3; probe and fallback.add_project_arguments( - '-fstrict-flex-arrays=3', # C23 default; makes UB obvious + # strict flex arrays: prefer =3, fallback to =2 if needed + # (inserted just above via detection) '-Wdouble-promotion',Add the detection above the add_project_arguments block:
+# Detect strict flex-array support +strict_flags = cc.get_supported_arguments(['-fstrict-flex-arrays=3', '-fstrict-flex-arrays=2']) +if strict_flags.length() > 0 + add_project_arguments(strict_flags[0], language: 'c') +endif
133-141: Prefer treating CRoaring includes as system via dependency, not raw -isystem.Using pkg-config’s includedir as
-isystemis coarse; let Meson mark the dep as system.-# Mark roaring headers as system includes to suppress third-party warnings -roaring_inc_args = [] -if roaring_dep.found() - # Use modern API that works with any dependency type - roaring_inc_dir = roaring_dep.get_variable(pkgconfig: 'includedir', default_value: '') - if roaring_inc_dir != '' - roaring_inc_args = ['-isystem', roaring_inc_dir] - endif -endif +roaring_sys_dep = roaring_dep +if roaring_dep.found() and roaring_dep.has_method('as_system') + roaring_sys_dep = roaring_dep.as_system('system') +endif- dependencies : [libsodium_dep, libgit2_dep, thread_dep, roaring_dep], - c_args : roaring_inc_args + dependencies : [libsodium_dep, libgit2_dep, thread_dep, roaring_sys_dep], + c_args : ['-ffreestanding']Also applies to: 142-149
352-369: Add newly public headers to standalone compile checks.Include CBOR constants and ref utils headers to catch drift.
public_headers = [ 'include/gitmind/output.h', 'include/gitmind/constants.h', + 'include/gitmind/cbor/constants_cbor.h', 'include/gitmind/error.h', 'include/gitmind/safety.h', 'core/include/gitmind/result.h', 'core/include/gitmind/types.h', 'core/include/gitmind/context.h', 'core/include/gitmind/attribution.h', 'core/include/gitmind/edge.h', 'core/include/gitmind/edge_attributed.h', 'core/include/gitmind/journal.h', 'core/include/gitmind/cache.h', 'core/include/gitmind/io/io.h', 'core/include/gitmind/time/time.h', 'core/include/gitmind/util/memory.h', + 'core/include/gitmind/util/ref.h', 'core/include/gitmind/utf8/validate.h', ]
161-225: DRY repeated test dependencies.Hoist
[libsodium_dep, libgit2_dep, thread_dep]into a variable and reuse.+# After deps: +core_test_deps = [libsodium_dep, libgit2_dep, thread_dep]Example usage:
test_error = executable('test_error', 'core/tests/unit/test_error.c', include_directories : inc, link_with : libgitmind, - dependencies : [libsodium_dep, libgit2_dep, thread_dep]) + dependencies : core_test_deps)
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
core/tests/unit/test_cache_branch_limits.c(1 hunks)core/tests/unit/test_cache_tree_size.c(1 hunks)docs/features/Features_Ledger.md(1 hunks)meson.build(7 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- core/tests/unit/test_cache_tree_size.c
- docs/features/Features_Ledger.md
- core/tests/unit/test_cache_branch_limits.c
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: flyingrobots
PR: neuroglyph/git-mind#169
File: docs/templates/code-review-feedback.md:26-33
Timestamp: 2025-09-16T17:10:27.450Z
Learning: The user (flyingrobots) uses Obsidian to view/edit Markdown files and prefers to keep Obsidian-specific syntax like collapsible callout markers (e.g., `[!NOTE]-` for collapsible callouts) even if they're not GitHub-compatible.
📚 Learning: 2025-09-15T01:19:37.384Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: docs/code-review/CLAUDE.md:0-0
Timestamp: 2025-09-15T01:19:37.384Z
Learning: Applies to docs/code-review/**/meson.build : Do not hardcode `c_std=c23`; detect compiler support or provide a compatible minimum standard with feature checks
Applied to files:
meson.build
📚 Learning: 2025-09-13T03:13:54.145Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-09-13T03:13:54.145Z
Learning: Use Meson/Ninja for build and tests; run lint and gauntlet locally; keep diffs minimal and pass CI with zero new clang-tidy warnings
Applied to files:
meson.build
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
🔇 Additional comments (6)
meson.build (6)
13-32: Host-build hard stop: LGTM.Clear guidance and safe overrides; aligns with Docker/CI-first policy.
126-127: gm_build_ref source wired: LGTM.Ref utils now part of the library; matches tests/docs.
130-131: Include dirs unified: LGTM.Public + core headers via
inclooks correct.
166-173: Linking unit tests against libgit2: LGTM.Consistent deps across tests; avoids ODR/link gaps after ref utils.
Also applies to: 178-185, 190-191, 210-217, 224-224, 230-231, 236-237, 242-243, 248-249, 254-255, 260-261, 266-267
286-315: New tests added: LGTM.Good coverage for branch limits, shard distribution, tree size, OID fallback, and ref utils.
343-348: Test registrations: LGTM (no duplicates).Previous duplication fixed.
left a comment
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (7)
docs/talk-shop/Sandbox_Transactions.md (7)
37-46: Call out ref-construction invariants (align with gm_build_ref).Explicitly document that branch inputs must not start with "refs/" and are normalized/validated; this prevents double-prefixing and keeps the RFC consistent with gm_build_ref and the new GITMIND_EDGES_REF_PREFIX work.
refs/gitmind/ pending/<txn-id> # sandbox transaction refs applied/<txn-id> # (optional) archive for auditing-- Transaction IDs are ULIDs; metadata stored under
refs/gitmind/pending/<txn-id>/meta.
-- Payload edges live underrefs/gitmind/pending/<txn-id>/edges/<branch>mirroring the canonical layout so reuse is easy.
+- Transaction IDs are ULIDs; metadata stored underrefs/gitmind/pending/<txn-id>/meta.
+- Payload edges live underrefs/gitmind/pending/<txn-id>/edges/<branch>mirroring the canonical layout so reuse is easy.
+
+> [!NOTE]-
+> Ref construction invariants:
+> - Branch inputs must be Git-style names and must NOT begin withrefs/(to avoid double-prefixing).
+> - All refs are constructed viagm_build_ref(out, sz, prefix, branch)with bounds checks and libgit2 normalization.
49-51: Clarify “default” behavior to avoid confusion with Phase 2/3 gating.Reads/writes are only redirected when a transaction is active (env/flag). Wording “by default” here conflicts with Phases 2–3.
-2. Subsequent `git mind link/list/...` commands operate inside the transaction by default (reads merge pending + canonical, writes hit pending). +2. When a transaction is active, subsequent `git mind link/list/...` commands operate inside it (reads merge pending + canonical, writes hit pending).
56-59: Specify atomic ref update (CAS) to prevent TOCTOU races.State that updates to
refs/gitmind/edges/<branch>must use compare-and-swap with the recorded base OID (libgit2 expected-old-id), failing fast on mismatch.- Confirm the canonical journal tip still equals the recorded base OID (fast-forward); else replay on top (append new commits). -- Update `refs/gitmind/edges/<branch>` and move the transaction ref under `refs/gitmind/applied/<txn-id>` (or delete if retention not needed). +- Update `refs/gitmind/edges/<branch>` using an atomic expected-old-OID write; on mismatch, abort and retry replay. Then move the transaction ref under `refs/gitmind/applied/<txn-id>` (or delete if retention not needed).
62-64: Abort policy: also guard against foreign/immutable txns.Add a note that abort must refuse txns owned by others (if namespaced) and any txn already finalized on the remote, enforced by server-side hooks.
- Drop the pending ref; the CLI should refuse to abort if the transaction was already applied to avoid footguns. + - Drop the pending ref; the CLI should refuse to abort if the transaction was already applied or is not owned by the caller (if namespaced), with server-side hook enforcement.
71-74: Provide refspec examples to keep pending refs out of pushes by default.Offer concrete push/fetch refspecs so pending/applied never leak unless explicitly requested.
- Hooks (pre-push) should whitelist pending refs or ignore them entirely. +- Hooks (pre-push) should whitelist pending refs or ignore them entirely. Recommended refspecs: + +```ini +# .git/config (local) +[remote "origin"] + fetch = +refs/heads/*:refs/remotes/origin/* # normal branches + fetch = +refs/gitmind/edges/*:refs/remotes/origin/gitmind/edges/* + # Intentionally omit pending/applied + push = +refs/heads/*:refs/heads/* + push = +refs/gitmind/edges/*:refs/gitmind/edges/* +```
88-89: Typo: “gm mind” → “git mind”.Align CLI naming with earlier sections.
-- **Merge tool** – do we want a `gm mind txn rebase` to restack the transaction on a new base before applying? +- **Merge tool** – do we want a `git mind txn rebase` to restack the transaction on a new base before applying?
35-46: Consider user- or namespace-scoped pending refs to reduce collisions and enable ACLs.Design tweak:
refs/gitmind/pending/<user>/<txn-id>andapplied/<user>/<txn-id>simplifies ownership checks and pruning.- pending/<txn-id> # sandbox transaction refs - applied/<txn-id> # (optional) archive for auditing + pending/<user>/<txn-id> # sandbox transaction refs (namespaced) + applied/<user>/<txn-id> # (optional) archive for auditingAlso applies to: 83-90
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
docs/talk-shop/Sandbox_Transactions.md(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Files:
docs/talk-shop/Sandbox_Transactions.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Files:
docs/talk-shop/Sandbox_Transactions.md
🧠 Learnings (1)
📓 Common learnings
Learnt from: flyingrobots
PR: neuroglyph/git-mind#169
File: docs/templates/code-review-feedback.md:26-33
Timestamp: 2025-09-16T17:10:27.450Z
Learning: The user (flyingrobots) uses Obsidian to view/edit Markdown files and prefers to keep Obsidian-specific syntax like collapsible callout markers (e.g., `[!NOTE]-` for collapsible callouts) even if they're not GitHub-compatible.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
🔇 Additional comments (1)
docs/talk-shop/Sandbox_Transactions.md (1)
91-96: Docs link & TOC checks passed — no action required.Link and TOC checks for docs/talk-shop/Sandbox_Transactions.md succeeded; referenced files (docs/talk-shop/Graph-Lvl-Up-Tank.md, docs/features/Features_Ledger.md, core/tests/unit/test_cache_branch_limits.c, core/tests/unit/test_cache_tree_size.c) are present.
left a comment
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (6)
docs/features/Features_Ledger.md (6)
50-50: Fix broken anchor to Milestone_Synthesis.md (MVP).-See `docs/planning/Milestone_Synthesis.md#mvpmmdash-show-hn-ready`. +See `docs/planning/Milestone_Synthesis.md#mvp-show-hn-ready`.
65-65: Fix broken anchor to Milestone_Synthesis.md (Alpha).-See `docs/planning/Milestone_Synthesis.md#alpha-mdash-team-productivity`. +See `docs/planning/Milestone_Synthesis.md#alpha-team-productivity`.
84-84: Fix broken anchor to Milestone_Synthesis.md (Beta).-See `docs/planning/Milestone_Synthesis.md#beta-mdash-community-onboarding`. +See `docs/planning/Milestone_Synthesis.md#beta-community-onboarding`.
100-100: Fix broken anchor to Milestone_Synthesis.md (v1.0.0).-See `docs/planning/Milestone_Synthesis.md#v100-mdash-production-grade`. +See `docs/planning/Milestone_Synthesis.md#v1-0-0-production-grade`.
22-27: Replace placeholder formulas with concrete definitions.Placeholders will fail docs gates and are unclear. Provide explicit formulas.
-${formula where features are weighted based on their estimated complexity}$ +Milestone progress = Σ(weight_i × completion_i) / Σ(weight_i), +where weight_i is each feature’s normalized complexity (e.g., KLoC or story‑points) within that milestone. -${overall progress formula}$ +Overall progress = Σ(W_m × progress_m) / Σ(W_m), +where W_m are milestone weights defined in the roadmap (e.g., MVP=1, Alpha=1, Beta=1, v1.0.0=2).
30-39: Fix stray code fence and clean up milestone table text.Unmatched fence breaks rendering; table has an invalid separator row and informal remarks.
-``` | Milestone | % | Remarks | |-----------|---|------------| -| MVP | `██████████████████████████████░░░░░░░░░░ 74%` | Min. Viable Product | -| Alpha | `█████████████████████████████▓░░░░░░░░░░ 73%` | Comes before Beta | -| Beta | `██████████████████████░░░░░░░░░░░░░░░░░░ 55%` | Half way | -| v1.0.0 | `█████████████████████████████████░░░░░░░ 82%` | Lol what? | -| --- | -| Total | `█████████████████████████████░░░░░░░░░░░ 72%` | Math don't be mathin' | +| MVP | `██████████████████████████████░░░░░░░░░░ 74%` | Minimum Viable Product | +| Alpha | `█████████████████████████████▓░░░░░░░░░░ 73%` | Pre‑Beta stabilization phase | +| Beta | `██████████████████████░░░░░░░░░░░░░░░░░░ 55%` | Midway hardening | +| v1.0.0 | `█████████████████████████████████░░░░░░░ 82%` | Scope nearly stable | +| Total | `█████████████████████████████░░░░░░░░░░░ 72%` | Totals use milestone weights (see formulas below) |
🧹 Nitpick comments (3)
docs/features/Features_Ledger.md (3)
156-156: Normalize status label “V1” → “v1.0.0”.Keep milestone names consistent across the doc.
-| 🧰 | Safe String/Memory | Core | — | core/include/gitmind/util | v1.0.0 | 0.4 | V1 | 90% | █████████░ | Safe wrappers adopted in hot paths. | Sweep stragglers; docs. | Unit | Security uplift. | +| 🧰 | Safe String/Memory | Core | — | core/include/gitmind/util | v1.0.0 | 0.4 | v1.0.0 | 90% | █████████░ | Safe wrappers adopted in hot paths. | Sweep stragglers; docs. | Unit | Security uplift. |
180-180: Normalize status label “V1” → “v1.0.0”.-| 🧪 | Worksheet Gates | DX | docs/tools | tools/review | Alpha | 0.3 | V1 | 90% | █████████░ | Pre‑push checks for placeholders + decisions. | Heuristics later (optional). | Scripted | Keeps quality high. | +| 🧪 | Worksheet Gates | DX | docs/tools | tools/review | Alpha | 0.3 | v1.0.0 | 90% | █████████░ | Pre‑push checks for placeholders + decisions. | Heuristics later (optional). | Scripted | Keeps quality high. |
8-8: Bump last_updated after edits.Update the front‑matter timestamp when you land the fixes.
[raise_nitpick_refactor]
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
docs/features/Features_Ledger.md(1 hunks)docs/planning/Milestone_Synthesis.md(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- docs/planning/Milestone_Synthesis.md
🧰 Additional context used
📓 Path-based instructions (2)
**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Comply with repository markdown lint rules (.markdownlint.jsonc); use make md-lint / make md-fix
Files:
docs/features/Features_Ledger.md
docs/**/*.md
📄 CodeRabbit inference engine (AGENTS.md)
Docs must pass link and TOC checks (tools/docs/check_docs.py --mode link|toc)
Files:
docs/features/Features_Ledger.md
🧠 Learnings (1)
📓 Common learnings
Learnt from: flyingrobots
PR: neuroglyph/git-mind#169
File: docs/templates/code-review-feedback.md:26-33
Timestamp: 2025-09-16T17:10:27.450Z
Learning: The user (flyingrobots) uses Obsidian to view/edit Markdown files and prefers to keep Obsidian-specific syntax like collapsible callout markers (e.g., `[!NOTE]-` for collapsible callouts) even if they're not GitHub-compatible.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Compat Canaries (non-blocking) (clang-19)
- GitHub Check: Compat Canaries (non-blocking) (clang-18)
- GitHub Check: Compat Canaries (non-blocking) (gcc-13)
- GitHub Check: Compat Canaries (non-blocking) (gcc-12)
🔇 Additional comments (1)
docs/features/Features_Ledger.md (1)
58-61: Confirm markdownlint/link/TOC pass for Obsidian callouts ([!INFO])Obsidian callouts ([!INFO]) are acceptable; ensure markdownlint and the docs link/TOC checks pass for docs/features/Features_Ledger.md — lines 58–61, 73–81, 92–97, 108–113, 200–249. Run locally and paste outputs:
make md-lint || true,python3 tools/docs/check_docs.py --mode link docs/features/Features_Ledger.md,python3 tools/docs/check_docs.py --mode toc docs/features/Features_Ledger.md
b8dcb2b to
f531dc1
Compare
f531dc1 to
62577ae
Compare
This PR addresses the latest architecture/API and safety review items and adds a small CHANGELOG workflow.
Highlights
Changelog automation
make changelog-add m="One-liner" n="Optional note"HOOKS_BYPASS=1 git push)Journal + refs alignment
GITMIND_EDGES_REF_PREFIX(refs/gitmind/edges/)gm_build_ref(out, sz, prefix, branch)for safe ref construction + branch validationgm_build_refConstants unification
core/include/gitmind/constants.h(public constants live ininclude/gitmind/constants.h)include/gitmind/cbor/constants_cbor.hand removed internal duplicatePath + safety sweeps
GM_PATH_MAX=4096, removed*2path buffers, added bounds-checked ref/path building withgm_snprintfextern "C"wrappers to public headers; attribution.h now includes edge_attributed.h to avoid duplicationTests
Docs
Why
Follow-ups
Summary by CodeRabbit
New Features
Refactor
Tests
Documentation