Skip to content

Add hex ports, cache coordinators, and journal adapter robustness - #177

Merged
flyingrobots merged 49 commits into
mainfrom
feat/hex-ports-ci-green
Oct 9, 2025
Merged

Add hex ports, cache coordinators, and journal adapter robustness#177
flyingrobots merged 49 commits into
mainfrom
feat/hex-ports-ci-green

Conversation

@flyingrobots

@flyingrobots flyingrobots commented Oct 8, 2025

Copy link
Copy Markdown
Owner

Summary

This PR advances the hexagonal migration by introducing explicit ports and thin coordinators, improving journal robustness, and ensuring CI parity:

  • Add outbound ports: gm_logger_port, gm_metrics_port (umbrella-safe, no-op friendly).
  • Add default adapters: stdio logger + null metrics.
  • Extend gm_context_t with logger/metrics (appended at tail; no ABI break).
  • Add inbound cache coordinators: cache_build_port + cache_query_port delegating to existing APIs.
  • Extract pure cache staleness helper to domain header and use it from cache query.
  • Harden journal + libgit2 adapter paths for first-commit and ref creation/update.
  • Fix docs links and add required front matter/SPDX; add migration-progress.md tracker.

Change Areas

  • Core library (C)
  • Ports/Adapters (logger, metrics, cache)
  • Journal/write path + libgit2 adapter
  • Documentation (front matter, link hygiene, tracker)
  • CLI / UX
  • Build/CI workflows

Risk

  • Low — changes are additive (new headers/files, tail-appends) and guarded by tests.
  • Medium
  • High

Mitigations: All tests pass in Docker (32/32). make ci-local is green (docs + build + tests + clang-tidy). New functionality defaults to safe no-op adapters.

Code Review Guidance

  • Focus on the new port headers and thin coordinators:
    • core/include/gitmind/ports/{logger_port,metrics_port}.h
    • core/include/gitmind/ports/{cache_build_port,cache_query_port}.h
    • core/src/ports/cache/{cache_build_port.c,cache_query_port.c}
  • Adapters:
    • core/src/adapters/logging/stdio_logger_adapter.{c,h}
    • core/src/adapters/metrics/null_metrics_adapter.{c,h}
  • Journal + adapter robustness:
    • core/src/journal/writer.c (ref update, missing-parent tolerance)
    • core/src/adapters/git/libgit2_repository_port.c (ref dir creation, signature fallback)
  • Domain extraction:
    • core/include/gitmind/cache/internal/staleness.h
    • core/src/cache/query.c usage

Validation: run make ci-local (Dockerized). All tests pass; docs/link checks are green. The migration tracker (migration-progress.md) lists the completed steps.

Summary by CodeRabbit

  • New Features

    • Configurable logging (text/JSON), metrics, and diagnostics events with env-based tags.
    • CLI: added --json, refined --verbose/--porcelain; stderr logger and optional diagnostics wiring.
    • New integration ports for cache build/query and journal commands.
  • Bug Fixes

    • More robust Git operations: auto-creates ref directories, fallback author signature, safer non-fast-forward handling.
    • Safer cache staleness checks and shard prefixing.
  • Documentation

    • Added Observability, Telemetry Config, Diagnostics Events, and architecture guides; CLI quickstart and scripting patterns.
    • Removed/condensed outdated CLI and attribution docs; planning/roadmap docs converted to placeholders.

… context; wire in build\n\n- Add gm_logger_port and gm_metrics_port headers (umbrella-safe, no-op wrappers)\n- Add stdio logger + null metrics adapters under core/src/adapters/**\n- Append logger/metrics to gm_context_t at tail (no ABI break)\n- Update meson build + header checks\n\nCI: builds/tests remain green in container
…dinators; wire into build\n\n- cache_build_port.h and cache_query_port.h (vtbls)\n- default coordinators in core/src/ports/cache/** delegating to existing APIs\n- meson updated to compile new coordinators\n\nGreen CI in container
…; use from cache query\n\n- New internal header cache/internal/staleness.h (pure, inline)\n- gm_cache_is_stale uses gm_cache_staleness_time for age check
…cache flows\n\n- Tolerate missing parent ref during journal commit (empty history)\n- Update provided ref after journal commit\n- Create ref parent directories for custom namespaces; respect force flag\n- Signature fallback for bare repos\n\nAll tests pass in container
…d record status\n\n- Add minimal PRDs, planning, specs, and wishlist placeholders with frontmatter\n- Add/refresh migration-progress.md (tracker)\n- CI docs link checks pass
@coderabbitai

coderabbitai Bot commented Oct 8, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Introduces telemetry (logs/metrics/diagnostics) infrastructure and DI seams; adds logger/metrics/diagnostic ports and adapters; implements cache and journal driving/query ports; adds journal codec/plan/read decoding; instruments cache rebuild and journal read/write with telemetry; factors cache OID prefix and staleness helpers; updates CLI to wire logging/diagnostics; expands tests and build integration; broad docs overhaul.

Changes

Cohort / File(s) Summary
Cache internals & services
core/include/gitmind/cache/internal/staleness.h, core/include/gitmind/cache/internal/oid_prefix.h, core/src/domain/cache/oid_prefix.c, core/src/cache/query.c, core/src/app/cache/cache_rebuild_service.c
New staleness helper; OID shard prefix API/impl; cache query uses helper; cache rebuild gains telemetry/diagnostics, stable temp handling, optional out commit OID.
Telemetry core (config & formatting)
core/include/gitmind/telemetry/internal/config.h, core/src/telemetry/config.c, core/include/gitmind/telemetry/internal/log_format.h, core/src/telemetry/log_format.c
Adds environment-driven telemetry config (tags, log level/format, extras) and default log formatter (text/JSON).
Context & Ports API
core/include/gitmind/context.h, core/include/gitmind/ports/logger_port.h, core/include/gitmind/ports/metrics_port.h, core/include/gitmind/ports/diagnostic_port.h, core/include/gitmind/ports/cache_build_port.h, core/include/gitmind/ports/cache_query_port.h, core/include/gitmind/ports/journal_command_port.h
Extends context with logger/metrics/diagnostics/formatter; introduces logger, metrics, diagnostics ports with safe wrappers; adds cache build/query and journal command driving ports.
Ports implementations
core/src/ports/cache/cache_build_port.c, core/src/ports/cache/cache_query_port.c, core/src/ports/journal/journal_command_port.c
Implements driving ports: allocate state, validate args, delegate to domain APIs, translate results, dispose.
Adapters (logging/metrics/diagnostics)
core/src/adapters/logging/stdio_logger_adapter.h, .../stdio_logger_adapter.c, core/src/adapters/metrics/null_metrics_adapter.h, .../null_metrics_adapter.c, core/src/adapters/diagnostics/stderr_diagnostics_adapter.h, .../stderr_diagnostics_adapter.c
Adds stdio logger, null metrics, and stderr diagnostics adapters with init/dispose and vtbls.
Journal domain & coordinators
core/include/gitmind/journal/internal/append_plan.h, core/include/gitmind/journal/internal/codec.h, core/include/gitmind/journal/internal/read_decoder.h, core/src/domain/journal/append_planner.c, core/src/domain/journal/codec.c, core/src/domain/journal/read_decoder.c, core/src/journal/writer.c, core/src/journal/reader.c
Adds commit planning and base64/CBOR codec; edge read decoder (legacy/attributed); writer/reader refactor to use helpers and add telemetry/diagnostics, timing, and error propagation.
Git adapter update
core/src/adapters/git/libgit2_repository_port.c
Fallback signature creation; ensure ref path directories; adjust non-FF rejection to respect force.
CLI changes
apps/cli/main.c, apps/cli/README.md, apps/cli/Scripting_Patterns.md, apps/cli/link.md, apps/cli/list.md, apps/cli/main.md
Adds --json flag handling; wires stdio logger and optional diagnostics adapter; documents output channels, recipes, safety, scripting patterns.
Build & housekeeping
meson.build, .gitignore
Integrates new sources/headers, adapters, and tests; adds ignore paths for temp/cache dirs.
Tests — fakes
core/tests/fakes/logging/*, core/tests/fakes/metrics/*, core/tests/fakes/diagnostics/*, core/tests/fakes/git/fake_git_repository_port.c
Adds fake ports for logger/metrics/diagnostics; extends fake git repo to record commits on ref updates.
Tests — unit
core/tests/unit/test_log_formatter.c, test_cache_oid_prefix.c, test_cache_telemetry_emit.c, test_telemetry_cfg.c, test_cli_json_env.c, test_diagnostics_port.c, test_journal_port.c, test_journal_port_append_flow.c, test_journal_nff_retry.c, test_journal_e2e_libgit2.c
New coverage for formatter, OID prefix, telemetry config/tags, cache/journal telemetry and ports, diagnostics, CLI env, retry behavior, and libgit2 E2E.
Tests — integration & support
core/tests/integration/*, core/tests/support/temp_repo_helpers.h
Migrate to temp FS-backed repos; add repo tree build test; introduce temp repo helper/provider.
Docs — architecture/operations
docs/architecture/*, docs/operations/*, docs/README.md, README.md, AGENTS.md, migration-progress.md
Adds system/journal/cache/ref validation/hexagonal docs; observability and diagnostics events; updates indexes and guidelines; migration tracker.
Docs — planning/specs/PRDs
docs/planning/*, docs/specs/Technical_Specifications.md, docs/PRDs/*
Replace with placeholders and simplified structures.
Docs — removals (CLI & attribution & review artifacts)
docs/cli/* (deleted), docs/architecture/attribution-*.md (deleted), docs/code-reviews/* (deleted)
Removes legacy CLI, attribution system docs, and preserved review artifacts.
Docs — misc
docs/requirements/Requirements.md, docs/risk/Risk_Register.md
Minor heading/license updates.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI as CLI
  participant BuildPort as Cache Build Port
  participant Service as Cache Rebuild Service
  participant Repo as Git Repo Port
  participant Log as Logger Port
  participant Met as Metrics Port
  participant Diag as Diagnostics Port

  User->>CLI: gitmind cache-rebuild (--json/--verbose)
  CLI->>BuildPort: request_build(branch, force_full)
  BuildPort->>Service: gm_cache_rebuild_execute(ctx, branch)
  Service->>Log: log(event=rebuild_start, tags)
  Service->>Diag: emit(component=cache, event=rebuild_start, kvs)
  Service->>Repo: build_tree_from_directory(...)
  alt success
    Service->>Repo: commit_create + reference_update
    Service->>Met: timing_ms(name=cache.rebuild.duration_ms)
    Service->>Met: gauge_set/counter_add (edges_total, tree_size)
    Service->>Log: log(event=rebuild_ok, tags)
  else failure
    Service->>Diag: emit(..., event=rebuild_*_failed, code)
    Service->>Log: log(event=rebuild_failed, code)
  end
  Service-->>BuildPort: result
  BuildPort-->>CLI: result
Loading
sequenceDiagram
  autonumber
  participant Client as Client
  participant JPort as Journal Command Port
  participant Writer as Journal Writer
  participant Codec as Codec/Planner
  participant Repo as Git Repo Port
  participant Reader as Journal Reader
  participant Log as Logger
  participant Met as Metrics
  participant Diag as Diagnostics

  Client->>JPort: append(edges)
  JPort->>Writer: gm_journal_append(...)
  Writer->>Log: log(journal_append_start, tags)
  Writer->>Codec: encode message + build commit plan
  Writer->>Repo: commit_create + reference_update
  alt success
    Writer->>Met: timing(counter edges_total)
    Writer->>Log: log(journal_append_ok)
  else NFF retry
    Writer->>Diag: emit(journal_nff_retry)
    Writer->>Repo: reference_update (retry)
  end

  Client->>Reader: walk_journal(...)
  Reader->>Log: log(journal_read_start, tags)
  Reader->>Repo: walk_commits / read messages
  Reader->>Codec: decode edge(s)
  alt success
    Reader->>Met: timing(counter edges_total)
    Reader->>Log: log(journal_read_ok)
  else failure
    Reader->>Diag: emit(journal_read_failed, code)
    Reader->>Log: log(journal_read_failed, code)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Poem

hop hop, I wire the logs just so,
metrics count the edges’ flow.
diagnostics whisper where bugs hide,
cache and journal now instrumented wide.
ports abound, adapters cheer—
hexagons bloom, the path is clear. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The description includes a summary and code review guidance but diverges from the required template by using custom change area categories and a severity scale under Risk instead of the prescribed checkbox list of Behavior change, Public API change, and Docs-only. Please update the Change Areas and Risk sections to match the repository’s template by using the exact headings and checkboxes (e.g., Behavior change, Public API change, Docs-only) under Risk and the defined categories under Change Areas.
Docstring Coverage ⚠️ Warning Docstring coverage is 9.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title succinctly captures the primary additions of hexagonal ports, cache coordinators, and improvements to journal adapter robustness, reflecting the key changes without listing file names or extraneous details.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/hex-ports-ci-green

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 836ad12 and 0fd691a.

📒 Files selected for processing (26)
  • core/include/gitmind/cache/internal/staleness.h (1 hunks)
  • core/include/gitmind/context.h (2 hunks)
  • core/include/gitmind/ports/cache_build_port.h (1 hunks)
  • core/include/gitmind/ports/cache_query_port.h (1 hunks)
  • core/include/gitmind/ports/logger_port.h (1 hunks)
  • core/include/gitmind/ports/metrics_port.h (1 hunks)
  • core/src/adapters/git/libgit2_repository_port.c (3 hunks)
  • core/src/adapters/logging/stdio_logger_adapter.c (1 hunks)
  • core/src/adapters/logging/stdio_logger_adapter.h (1 hunks)
  • core/src/adapters/metrics/null_metrics_adapter.c (1 hunks)
  • core/src/adapters/metrics/null_metrics_adapter.h (1 hunks)
  • core/src/cache/query.c (2 hunks)
  • core/src/journal/writer.c (2 hunks)
  • core/src/ports/cache/cache_build_port.c (1 hunks)
  • core/src/ports/cache/cache_query_port.c (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/code-reviews/PR177/47a1bf537feb065ef3cbac02a8bf78e75944111c.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/specs/Technical_Specifications.md (1 hunks)
  • docs/wish-list-features/README.md (1 hunks)
  • meson.build (2 hunks)
  • migration-progress.md (1 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use NOLINT to suppress clang-tidy warnings; ALWAYS fix the underlying issue

Files:

  • core/src/adapters/metrics/null_metrics_adapter.c
  • core/include/gitmind/cache/internal/staleness.h
  • core/src/adapters/metrics/null_metrics_adapter.h
  • core/src/ports/cache/cache_build_port.c
  • core/include/gitmind/ports/cache_query_port.h
  • core/src/adapters/logging/stdio_logger_adapter.h
  • core/src/adapters/git/libgit2_repository_port.c
  • core/src/journal/writer.c
  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/metrics_port.h
  • core/include/gitmind/ports/cache_build_port.h
  • core/src/ports/cache/cache_query_port.c
  • core/src/cache/query.c
  • core/src/adapters/logging/stdio_logger_adapter.c
  • core/include/gitmind/context.h
{core,src,apps,tests}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

{core,src,apps,tests}/**/*.{c,h}: Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths
Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required
Equality is OID-first; if both OIDs exist they must match; only fall back to SHA when OIDs are absent
Build refs via gm_build_ref and reject inputs that start with "refs/"
Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes
Formatting via .clang-format (LLVM style, 4 spaces, 80 cols, pointer alignment right); pre-commit runs clang-format
Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with t; header guards start with GITMIND
Includes: prefer specific headers; order/regroup per .clang-format; include-what-you-use
No new clang-tidy warnings; keep touched files tidy-clean
Surface failures via gm_result_t (and variants); ports must not return raw integers
Maintain one responsibility per translation unit where practical; split multi-concern files when touched
Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers
Zero output buffers before formatting/copying on error paths

Files:

  • core/src/adapters/metrics/null_metrics_adapter.c
  • core/include/gitmind/cache/internal/staleness.h
  • core/src/adapters/metrics/null_metrics_adapter.h
  • core/src/ports/cache/cache_build_port.c
  • core/include/gitmind/ports/cache_query_port.h
  • core/src/adapters/logging/stdio_logger_adapter.h
  • core/src/adapters/git/libgit2_repository_port.c
  • core/src/journal/writer.c
  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/metrics_port.h
  • core/include/gitmind/ports/cache_build_port.h
  • core/src/ports/cache/cache_query_port.c
  • core/src/cache/query.c
  • core/src/adapters/logging/stdio_logger_adapter.c
  • core/include/gitmind/context.h
core/src/adapters/**/*_adapter.c

📄 CodeRabbit inference engine (AGENTS.md)

Runtime adapters live under core/src/adapters//_adapter.c and expose factories returning the port vtable plus state with teardown hooks

Files:

  • core/src/adapters/metrics/null_metrics_adapter.c
  • core/src/adapters/logging/stdio_logger_adapter.c
core/include/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public headers under core/include must be umbrella-safe: compile standalone, include only what they use, stable header guards, and provide extern "C" when included from C++

Files:

  • core/include/gitmind/cache/internal/staleness.h
  • core/include/gitmind/ports/cache_query_port.h
  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/metrics_port.h
  • core/include/gitmind/ports/cache_build_port.h
  • core/include/gitmind/context.h
core/include/gitmind/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public structs in headers must avoid ABI breaks; append new fields at the struct tail and mark deprecated fields instead of removing

Files:

  • core/include/gitmind/cache/internal/staleness.h
  • core/include/gitmind/ports/cache_query_port.h
  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/metrics_port.h
  • core/include/gitmind/ports/cache_build_port.h
  • core/include/gitmind/context.h
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.md: Docs must have front matter first, a single H1, a '## Table of Contents', and the title must match the H1
Add api_version field to API docs front matter
Place License/SPDX comments immediately after front matter in docs
README and other Markdown must comply with markdownlint rules: underscore emphasis/strong, blockquote spacing, code fence formatting, no inline HTML wrappers, heading punctuation

Files:

  • docs/wish-list-features/README.md
  • docs/code-reviews/PR177/47a1bf537feb065ef3cbac02a8bf78e75944111c.md
  • docs/planning/Product_Roadmap.md
  • docs/PRDs/PRD-co-thought-mcp-service.md
  • docs/planning/Release_Plans.md
  • docs/planning/Sprint_Plans.md
  • docs/planning/Milestones.md
  • docs/specs/Technical_Specifications.md
  • docs/PRDs/PRD-git-mind-semantics-time-travel-prototype.md
core/src/adapters/**/*_adapter.h

📄 CodeRabbit inference engine (AGENTS.md)

Adapter private headers colocate under core/src/adapters//_adapter.h

Files:

  • core/src/adapters/metrics/null_metrics_adapter.h
  • core/src/adapters/logging/stdio_logger_adapter.h
core/src/ports/**

📄 CodeRabbit inference engine (AGENTS.md)

Default implementations for simple inbound coordinators that remain in C may live under core/src/ports/**

Files:

  • core/src/ports/cache/cache_build_port.c
  • core/src/ports/cache/cache_query_port.c
core/src/**/{hooks,cache,journal}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid direct libgit2 usage; route repository/ref operations through gm_git_repository_port/gm_git_ref_port adapters

Files:

  • core/src/ports/cache/cache_build_port.c
  • core/src/journal/writer.c
  • core/src/ports/cache/cache_query_port.c
  • core/src/cache/query.c
core/include/gitmind/ports/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

Files:

  • core/include/gitmind/ports/cache_query_port.h
  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/metrics_port.h
  • core/include/gitmind/ports/cache_build_port.h
meson.build

📄 CodeRabbit inference engine (AGENTS.md)

Target C23 via Meson c2x and keep warnings-as-errors; register new unit test targets in meson.build

Files:

  • meson.build
🧠 Learnings (6)
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to core/src/**/{hooks,cache,journal}/**/*.{c,h} : Avoid direct libgit2 usage; route repository/ref operations through gm_git_repository_port/gm_git_ref_port adapters

Applied to files:

  • core/src/adapters/git/libgit2_repository_port.c
  • meson.build
📚 Learning: 2025-10-01T04:13:25.749Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.749Z
Learning: Applies to core/include/gitmind/ports/**/*.h : Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

Applied to files:

  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/context.h
  • 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: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h

Applied to files:

  • core/include/gitmind/context.h
  • 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: Applies to include/gitmind/**/*.h : Public, namespaced headers live under include/gitmind/

Applied to files:

  • meson.build
📚 Learning: 2025-10-01T04:13:25.749Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.749Z
Learning: Applies to docs/activity/**/*.md : Document migration progress and lessons under docs/activity/<date>_hexagonal.md

Applied to files:

  • migration-progress.md
📚 Learning: 2025-10-01T04:13:25.749Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.749Z
Learning: Applies to docs/architecture/hexagonal/** : Track adapter status and migrations in docs/architecture/hexagonal/**; keep diagrams and status tables updated

Applied to files:

  • migration-progress.md
🧬 Code graph analysis (10)
core/src/adapters/metrics/null_metrics_adapter.c (1)
core/src/adapters/logging/stdio_logger_adapter.c (1)
  • gm_result_void_t (51-65)
core/src/adapters/metrics/null_metrics_adapter.h (1)
core/src/adapters/metrics/null_metrics_adapter.c (2)
  • gm_result_void_t (34-45)
  • gm_null_metrics_port_dispose (47-52)
core/src/ports/cache/cache_build_port.c (2)
core/src/cache/builder.c (1)
  • gm_cache_rebuild (9-19)
core/src/ports/cache/cache_query_port.c (1)
  • gm_result_void_t (72-87)
core/include/gitmind/ports/cache_query_port.h (1)
core/src/ports/cache/cache_query_port.c (2)
  • gm_result_void_t (72-87)
  • gm_qry_cache_port_dispose (89-96)
core/src/adapters/logging/stdio_logger_adapter.h (1)
core/src/adapters/logging/stdio_logger_adapter.c (2)
  • gm_result_void_t (51-65)
  • gm_stdio_logger_port_dispose (67-72)
core/src/journal/writer.c (1)
core/src/error/error.c (1)
  • gm_error_free (161-178)
core/include/gitmind/ports/cache_build_port.h (1)
core/src/ports/cache/cache_build_port.c (2)
  • gm_result_void_t (42-57)
  • gm_cmd_cache_build_port_dispose (59-64)
core/src/ports/cache/cache_query_port.c (2)
core/src/cache/query.c (3)
  • gm_cache_query_fanout (392-396)
  • gm_cache_query_fanin (399-403)
  • gm_cache_stats (415-448)
core/src/ports/cache/cache_build_port.c (1)
  • gm_result_void_t (42-57)
core/src/cache/query.c (1)
core/include/gitmind/cache/internal/staleness.h (1)
  • gm_cache_staleness_time (15-20)
core/src/adapters/logging/stdio_logger_adapter.c (1)
core/src/adapters/metrics/null_metrics_adapter.c (1)
  • gm_result_void_t (34-45)
🔇 Additional comments (23)
core/include/gitmind/ports/metrics_port.h (3)

1-10: LGTM!

Header guard, includes, and license header are correct and follow the project conventions.


20-34: Well-designed port interface.

The vtable-based design with non-owning vtbl pointer and opaque adapter state follows the hexagonal architecture pattern correctly. Function signatures are consistent and the tags parameter enables flexible metadata attachment.


36-62: Excellent null-safety pattern for optional metrics.

The inline wrappers correctly default to no-op success when the port or specific function is unset, which is the right behavior for optional observability features.

core/src/cache/query.c (2)

23-23: LGTM!

The new internal staleness header is appropriately included and positioned correctly among other internal headers.


175-177: Good refactor with improved robustness.

The centralized staleness helper adds a defensive check for now_time <= journal_tip_time, which prevents potential unsigned arithmetic issues with clock skew or test scenarios. This is a robustness improvement over the manual check.

migration-progress.md (1)

6-115: Excellent migration tracking structure.

The comprehensive checklist with clear modules, completion criteria, and verification steps provides a solid foundation for tracking the hexagonal architecture migration. The structure aligns well with the project's documented approach.

core/include/gitmind/cache/internal/staleness.h (2)

1-13: LGTM!

Header structure, guard naming, and includes are correct and follow project conventions.


14-20: Clean and correct staleness logic.

The function correctly handles edge cases (clock skew via the now_time <= journal_tip_time check) and provides clear staleness semantics. Good encapsulation for reuse across cache operations.

core/src/adapters/metrics/null_metrics_adapter.h (1)

1-21: LGTM!

Adapter header follows project conventions: correct header guard pattern, appropriate use of GM_NODISCARD on the init function, and proper location under core/src/adapters/metrics/.

core/include/gitmind/context.h (2)

15-16: LGTM!

New port header includes are correctly positioned and follow the existing include pattern.


47-54: Well-structured context extension.

The new logger and metrics ports are correctly appended at the struct tail, preserving ABI compatibility. The comment accurately describes their optional nature and the no-op behavior of wrappers when uninitialized.

core/src/adapters/logging/stdio_logger_adapter.h (1)

1-23: LGTM!

Adapter header is well-structured with correct header guard, appropriate includes (stdio.h for FILE*), and proper use of GM_NODISCARD on the init function. The signature design allowing FILE* and min_level configuration is sound.

core/src/adapters/metrics/null_metrics_adapter.c (2)

9-11: LGTM: Minimal state for null adapter.

The dummy state struct with _unused field maintains consistency with the dispose pattern and is safe, even though the adapter requires no actual state.


34-45: LGTM: Proper initialization with validation and error handling.

The function correctly validates inputs, handles allocation failure, and returns appropriate error codes following the port pattern.

core/src/ports/cache/cache_query_port.c (2)

16-31: LGTM: Proper fanout query wrapper with validation.

The implementation correctly validates all required inputs, retrieves state, delegates to the underlying API, and wraps the result appropriately.


50-64: LGTM: Stats implementation correctly handles optional outputs.

The function properly validates required inputs (self, state, branch) while allowing edge_count and cache_size_bytes to be NULL, which aligns with the underlying gm_cache_stats API contract.

core/src/adapters/logging/stdio_logger_adapter.c (1)

51-65: LGTM: Proper initialization and non-owning stream handling.

The function validates both port and stream, handles allocation failure correctly, and properly initializes the state. The dispose function correctly does not close the FILE* stream since it's non-owning.

core/include/gitmind/ports/cache_build_port.h (2)

29-32: LGTM: Proper port structure with non-owning vtbl.

The port struct correctly uses a const vtbl pointer and opaque state, following the standard port pattern and preventing accidental modification of the vtbl.


34-43: LGTM: Clean vtbl interface with appropriate return types.

The vtbl provides two operations with gm_result_void_t returns, properly surfacing failures per the coding guidelines that "ports must not return raw integers."

core/include/gitmind/ports/cache_query_port.h (2)

27-30: LGTM: Consistent port structure.

The port type follows the same pattern as other ports in the codebase, with a non-owning vtbl and opaque state.


32-50: LGTM: Well-designed query interface.

The vtbl provides separate operations for fanout (by source OID), fanin (by target OID), and statistics retrieval, with appropriate parameter types and consistent use of gm_result_void_t for error handling.

core/src/ports/cache/cache_build_port.c (2)

15-27: LGTM: Proper wrapper over cache rebuild API.

The function validates all required inputs, delegates to gm_cache_rebuild, and correctly wraps the integer result code into gm_result_void_t as required by the coding guidelines.


29-35: LGTM: Documented no-op invalidate is acceptable.

The best-effort no-op with clear documentation is appropriate for this initial port implementation. Future enhancements can add proper invalidation logic when needed.

Comment thread core/src/adapters/logging/stdio_logger_adapter.c
Comment thread docs/code-reviews/PR177/47a1bf537feb065ef3cbac02a8bf78e75944111c.md Outdated
Comment thread docs/planning/Milestones.md
Comment thread docs/planning/Product_Roadmap.md
Comment thread docs/planning/Release_Plans.md
Comment thread docs/PRDs/PRD-co-thought-mcp-service.md
Comment thread docs/PRDs/PRD-git-mind-semantics-time-travel-prototype.md
Comment thread docs/specs/Technical_Specifications.md
Comment thread docs/wish-list-features/README.md
Comment thread migration-progress.md
@flyingrobots flyingrobots changed the title Hex ports + cache coordinators + journal/adapter fixes (CI green) Add hex ports, cache coordinators, and journal adapter robustness Oct 8, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
core/include/gitmind/ports/logger_port.h (1)

7-7: Remove unused include.

The stddef.h include does not appear to be used in this header. The header only requires gm_result_void_t from gitmind/result.h.

Apply this diff to remove the unused include:

-#include <stddef.h>
-
 #include "gitmind/result.h"
core/include/gitmind/ports/cache_query_port.h (1)

61-65: Consider adding parameter documentation for the stats function.

The stats function could benefit from brief parameter descriptions (similar to query_fanout), clarifying what edge_count and cache_size_bytes represent and the expected behavior when the branch doesn't exist.

Example enhancement:

-    /** Retrieve cache statistics for a branch. */
+    /**
+     * Retrieve cache statistics for a branch.
+     * @param self             Port instance.
+     * @param branch           Branch name.
+     * @param edge_count       Output: total edges in cache for this branch.
+     * @param cache_size_bytes Output: approximate memory usage in bytes.
+     */
     gm_result_void_t (*stats)(gm_qry_cache_port_t *self,
                               const char *branch,
                               uint64_t *edge_count,
                               uint64_t *cache_size_bytes);
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cdc5f43 and 8b1d4f2.

📒 Files selected for processing (5)
  • core/include/gitmind/ports/cache_build_port.h (1 hunks)
  • core/include/gitmind/ports/cache_query_port.h (1 hunks)
  • core/include/gitmind/ports/logger_port.h (1 hunks)
  • core/include/gitmind/ports/metrics_port.h (1 hunks)
  • docs/code-reviews/PR177/3b7ce522e107011f8f92dc629facfa5b6a3595fb.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • core/include/gitmind/ports/metrics_port.h
  • core/include/gitmind/ports/cache_build_port.h
🧰 Additional context used
📓 Path-based instructions (6)
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.md: Docs must have front matter first, a single H1, a '## Table of Contents', and the title must match the H1
Add api_version field to API docs front matter
Place License/SPDX comments immediately after front matter in docs
README and other Markdown must comply with markdownlint rules: underscore emphasis/strong, blockquote spacing, code fence formatting, no inline HTML wrappers, heading punctuation

Files:

  • docs/code-reviews/PR177/3b7ce522e107011f8f92dc629facfa5b6a3595fb.md
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use NOLINT to suppress clang-tidy warnings; ALWAYS fix the underlying issue

Files:

  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/cache_query_port.h
{core,src,apps,tests}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

{core,src,apps,tests}/**/*.{c,h}: Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths
Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required
Equality is OID-first; if both OIDs exist they must match; only fall back to SHA when OIDs are absent
Build refs via gm_build_ref and reject inputs that start with "refs/"
Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes
Formatting via .clang-format (LLVM style, 4 spaces, 80 cols, pointer alignment right); pre-commit runs clang-format
Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with t; header guards start with GITMIND
Includes: prefer specific headers; order/regroup per .clang-format; include-what-you-use
No new clang-tidy warnings; keep touched files tidy-clean
Surface failures via gm_result_t (and variants); ports must not return raw integers
Maintain one responsibility per translation unit where practical; split multi-concern files when touched
Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers
Zero output buffers before formatting/copying on error paths

Files:

  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/cache_query_port.h
core/include/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public headers under core/include must be umbrella-safe: compile standalone, include only what they use, stable header guards, and provide extern "C" when included from C++

Files:

  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/cache_query_port.h
core/include/gitmind/ports/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

Files:

  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/cache_query_port.h
core/include/gitmind/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public structs in headers must avoid ABI breaks; append new fields at the struct tail and mark deprecated fields instead of removing

Files:

  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/cache_query_port.h
🧠 Learnings (1)
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to core/include/gitmind/ports/**/*.h : Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

Applied to files:

  • core/include/gitmind/ports/logger_port.h
🧬 Code graph analysis (1)
core/include/gitmind/ports/cache_query_port.h (1)
core/src/ports/cache/cache_query_port.c (2)
  • gm_result_void_t (72-87)
  • gm_qry_cache_port_dispose (89-96)
🔇 Additional comments (2)
core/include/gitmind/ports/logger_port.h (1)

33-76: LGTM!

The logger port design is well-structured and follows all guidelines:

  • POD structs with function-pointer vtables (as per coding guidelines)
  • Returns gm_result_void_t instead of raw integers
  • Sparse enum values (10/20/30/40) allow future extensibility
  • Inline wrapper provides safe no-op behavior when port is unset
  • Comprehensive documentation covers thread-safety and lifetime expectations
  • Umbrella-safe with proper C++ guards and minimal includes

The trivial inline wrapper correctly implements the safe no-op pattern mentioned in the design goals.

Based on learnings

core/include/gitmind/ports/cache_query_port.h (1)

1-79: LGTM! Well-structured inbound port following hexagonal architecture guidelines.

The port header is umbrella-safe, uses POD structs with function-pointer vtables, returns proper gm_result_void_t types, and documents memory ownership clearly. The lifecycle functions (init/dispose) match the implementation in cache_query_port.c, and all naming conventions are followed.

Comment thread docs/code-reviews/PR177/3b7ce522e107011f8f92dc629facfa5b6a3595fb.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (3)
docs/code-reviews/PR177/0d1b34b0ee501bc7b7b2d0a9fb82e06a37642c77.md (1)

1-90: LGTM! Port header follows guidelines.

The header is umbrella-safe with proper guards, follows the required POD struct + function-pointer vtbl pattern, and declares (but doesn't inline) lifecycle functions as specified. Documentation is comprehensive.

Note: There's a minor pattern inconsistency with logger_port.h — this port passes the entire gm_qry_cache_port_t *self to vtbl functions while logger_port.h passes only void *self. While both work, consistent patterns across ports would improve API predictability.

core/include/gitmind/ports/logger_port.h (1)

40-59: Consider port pattern consistency.

This port uses void *self in both the struct (line 42) and vtbl signature (line 55), whereas cache_query_port.h uses void *state in the struct and passes the entire gm_qry_cache_port_t * to vtbl functions.

For API predictability, consider standardizing the pattern across all ports. The current approach (passing just the state pointer) is more efficient but less flexible for multi-port scenarios.

core/include/gitmind/ports/cache_query_port.h (1)

7-14: Consider removing unused standard library includes.

The header includes stdbool.h and stddef.h, but neither bool nor size_t/NULL are used in the declarations. Only stdint.h (for uint64_t) is required. Removing unused includes aligns with the include-what-you-use guideline.

Apply this diff to remove unused includes:

-#include <stdbool.h>
-#include <stddef.h>
 #include <stdint.h>
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8b1d4f2 and f33dfc0.

📒 Files selected for processing (30)
  • .gm_cache_query_tmp/HEAD (1 hunks)
  • .gm_cache_query_tmp/config (1 hunks)
  • .gm_cache_query_tmp/description (1 hunks)
  • .gm_cache_query_tmp/hooks/README.sample (1 hunks)
  • .gm_cache_query_tmp/info/exclude (1 hunks)
  • .gm_cache_query_tmp/objects/21/943f67f4f74c4e95e464fed49773b2cdd90201 (1 hunks)
  • .gm_cache_query_tmp/objects/38/7b18948ca7f5a90328f210a8bdb9a31921511d (1 hunks)
  • .gm_cache_query_tmp/objects/3f/91d2035120c147e5a56e1b425d914fb0987bc8 (1 hunks)
  • .gm_cache_query_tmp/objects/97/11a7f1328e87390eacceb41e29f2bf9be83e0f (1 hunks)
  • .gm_cache_query_tmp/objects/b1/784fa26fc13a9305a66378693c180d89edff40 (1 hunks)
  • .gm_cache_query_tmp/objects/bd/ad5e8ce0946d7d4fd942975062575b27b34764 (1 hunks)
  • .gm_cache_query_tmp/objects/e2/db68efc1d70cb7d07963ef63f17757c2231b9b (1 hunks)
  • .gm_cache_query_tmp/objects/ec/8d09625e4264e13ceb2eb50b7b28e97ca58cfe (1 hunks)
  • .gm_cache_query_tmp/objects/fc/7c7afad58fbf322f23a2848a4462887a98bc52 (1 hunks)
  • .gm_cache_query_tmp/refs/gitmind/cache/testq (1 hunks)
  • .gm_cache_query_tmp/refs/gitmind/edges/testq (1 hunks)
  • .gm_cache_query_tmp/refs/heads/testq (1 hunks)
  • core/include/gitmind/ports/cache_query_port.h (1 hunks)
  • core/include/gitmind/ports/logger_port.h (1 hunks)
  • docs/README.md (1 hunks)
  • docs/architecture/attribution-integration-guide.md (0 hunks)
  • docs/architecture/attribution-system.md (0 hunks)
  • docs/architecture/attribution-use-cases.md (0 hunks)
  • docs/architecture/augments.md (1 hunks)
  • docs/architecture/cache-architecture.md (1 hunks)
  • docs/architecture/journal-architecture.md (1 hunks)
  • docs/architecture/ref-name-validation.md (1 hunks)
  • docs/architecture/system-overview.md (1 hunks)
  • docs/code-reviews/PR177/0d1b34b0ee501bc7b7b2d0a9fb82e06a37642c77.md (1 hunks)
  • docs/code-reviews/PR177/3b7ce522e107011f8f92dc629facfa5b6a3595fb.md (1 hunks)
💤 Files with no reviewable changes (3)
  • docs/architecture/attribution-integration-guide.md
  • docs/architecture/attribution-use-cases.md
  • docs/architecture/attribution-system.md
✅ Files skipped from review due to trivial changes (18)
  • .gm_cache_query_tmp/objects/21/943f67f4f74c4e95e464fed49773b2cdd90201
  • .gm_cache_query_tmp/HEAD
  • .gm_cache_query_tmp/objects/ec/8d09625e4264e13ceb2eb50b7b28e97ca58cfe
  • .gm_cache_query_tmp/refs/gitmind/edges/testq
  • .gm_cache_query_tmp/config
  • .gm_cache_query_tmp/objects/97/11a7f1328e87390eacceb41e29f2bf9be83e0f
  • .gm_cache_query_tmp/objects/fc/7c7afad58fbf322f23a2848a4462887a98bc52
  • .gm_cache_query_tmp/objects/bd/ad5e8ce0946d7d4fd942975062575b27b34764
  • .gm_cache_query_tmp/objects/3f/91d2035120c147e5a56e1b425d914fb0987bc8
  • .gm_cache_query_tmp/description
  • .gm_cache_query_tmp/info/exclude
  • .gm_cache_query_tmp/hooks/README.sample
  • .gm_cache_query_tmp/refs/gitmind/cache/testq
  • docs/architecture/cache-architecture.md
  • .gm_cache_query_tmp/objects/38/7b18948ca7f5a90328f210a8bdb9a31921511d
  • .gm_cache_query_tmp/refs/heads/testq
  • .gm_cache_query_tmp/objects/b1/784fa26fc13a9305a66378693c180d89edff40
  • docs/architecture/augments.md
🧰 Additional context used
📓 Path-based instructions (6)
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.md: Docs must have front matter first, a single H1, a '## Table of Contents', and the title must match the H1
Add api_version field to API docs front matter
Place License/SPDX comments immediately after front matter in docs
README and other Markdown must comply with markdownlint rules: underscore emphasis/strong, blockquote spacing, code fence formatting, no inline HTML wrappers, heading punctuation

Files:

  • docs/code-reviews/PR177/3b7ce522e107011f8f92dc629facfa5b6a3595fb.md
  • docs/README.md
  • docs/architecture/ref-name-validation.md
  • docs/code-reviews/PR177/0d1b34b0ee501bc7b7b2d0a9fb82e06a37642c77.md
  • docs/architecture/system-overview.md
  • docs/architecture/journal-architecture.md
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use NOLINT to suppress clang-tidy warnings; ALWAYS fix the underlying issue

Files:

  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/cache_query_port.h
{core,src,apps,tests}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

{core,src,apps,tests}/**/*.{c,h}: Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths
Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required
Equality is OID-first; if both OIDs exist they must match; only fall back to SHA when OIDs are absent
Build refs via gm_build_ref and reject inputs that start with "refs/"
Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes
Formatting via .clang-format (LLVM style, 4 spaces, 80 cols, pointer alignment right); pre-commit runs clang-format
Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with t; header guards start with GITMIND
Includes: prefer specific headers; order/regroup per .clang-format; include-what-you-use
No new clang-tidy warnings; keep touched files tidy-clean
Surface failures via gm_result_t (and variants); ports must not return raw integers
Maintain one responsibility per translation unit where practical; split multi-concern files when touched
Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers
Zero output buffers before formatting/copying on error paths

Files:

  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/cache_query_port.h
core/include/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public headers under core/include must be umbrella-safe: compile standalone, include only what they use, stable header guards, and provide extern "C" when included from C++

Files:

  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/cache_query_port.h
core/include/gitmind/ports/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

Files:

  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/cache_query_port.h
core/include/gitmind/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public structs in headers must avoid ABI breaks; append new fields at the struct tail and mark deprecated fields instead of removing

Files:

  • core/include/gitmind/ports/logger_port.h
  • core/include/gitmind/ports/cache_query_port.h
🧠 Learnings (2)
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to core/include/gitmind/ports/**/*.h : Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

Applied to files:

  • core/include/gitmind/ports/logger_port.h
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to docs/architecture/Ref_Name_Validation.md : Document and adhere to ref-name validation policy (reject leading refs/; normalize via libgit2) as specified

Applied to files:

  • docs/architecture/ref-name-validation.md
🧬 Code graph analysis (1)
core/include/gitmind/ports/cache_query_port.h (2)
core/src/ports/cache/cache_build_port.c (1)
  • gm_result_void_t (42-57)
core/src/ports/cache/cache_query_port.c (2)
  • gm_result_void_t (72-87)
  • gm_qry_cache_port_dispose (89-96)
🔇 Additional comments (4)
docs/code-reviews/PR177/3b7ce522e107011f8f92dc629facfa5b6a3595fb.md (1)

1-33: LGTM! Documentation compliance achieved.

All previously flagged issues have been addressed: the front matter title now matches the H1 heading, the SPDX/license block is correctly positioned after the front matter, and the Table of Contents section is present.

core/include/gitmind/ports/logger_port.h (2)

66-74: Verify inline wrapper aligns with port guidelines.

The inline wrapper gm_logger_log() provides safe no-op behavior when the port is unset, which aligns with the documented design goals. However, the coding guidelines specify "no non-trivial inline behavior" for ports.

While this wrapper is simple (null checks + delegation), ensure this pattern is acceptable. If approved, consider documenting this exception explicitly or updating guidelines to clarify what constitutes "non-trivial."

Based on learnings.


1-80: LGTM! Port header is umbrella-safe and well-documented.

The header follows the required POD struct + vtbl pattern with proper extern "C" guards, minimal includes, and stable header guards. Documentation clearly explains design goals, thread-safety expectations, and lifecycle ownership.

core/include/gitmind/ports/cache_query_port.h (1)

1-90: LGTM! Port design follows hexagonal architecture guidelines.

The cache query port header adheres to the port design guidelines:

  • POD struct with vtbl and opaque state
  • Function pointers return gm_result_void_t (no raw integers)
  • Umbrella-safe: standalone compilation, stable header guard, C++ extern guard
  • Clear memory ownership documentation for dynamically allocated results
  • Lifecycle functions marked with GM_NODISCARD for proper error handling

The thin coordinator design cleanly separates the port interface from implementation details.

Comment thread core/include/gitmind/ports/cache_query_port.h
Comment on lines +1 to +9
---
title: Project: No Tux Given 🐧⚡
description: Edge-journal commits with branch-aware graphs; the final architecture for storing semantics in Git.
audience: [developers]
domain: [architecture]
tags: [journal, cbor, refs]
status: stable
last_updated: 2025-09-15
---

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add the SPDX notice after the front matter

The documentation standard requires an SPDX/license comment immediately following the YAML header.

 ---
 title: Project: No Tux Given 🐧⚡
 description: Edge-journal commits with branch-aware graphs; the final architecture for storing semantics in Git.
 audience: [developers]
 domain: [architecture]
 tags: [journal, cbor, refs]
 status: stable
 last_updated: 2025-09-15
 ---
+<!-- SPDX-License-Identifier: Apache-2.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.

Suggested change
---
title: Project: No Tux Given 🐧⚡
description: Edge-journal commits with branch-aware graphs; the final architecture for storing semantics in Git.
audience: [developers]
domain: [architecture]
tags: [journal, cbor, refs]
status: stable
last_updated: 2025-09-15
---
---
title: Project: No Tux Given 🐧⚡
description: Edge-journal commits with branch-aware graphs; the final architecture for storing semantics in Git.
audience: [developers]
domain: [architecture]
tags: [journal, cbor, refs]
status: stable
last_updated: 2025-09-15
---
<!-- SPDX-License-Identifier: Apache-2.0 -->
🤖 Prompt for AI Agents
In docs/architecture/journal-architecture.md around lines 1 to 9, the YAML front
matter is present but missing the required SPDX/license comment immediately
after it; add a single-line SPDX identifier (e.g., "SPDX-License-Identifier:
Apache-2.0" or the project's chosen SPDX tag) on the line immediately following
the closing --- of the front matter so the file begins with the YAML block and
the SPDX notice directly after it.

Comment on lines +15 to +28
Table of Contents

- [Executive Summary](#executive-summary)
- [Core Design Principles](#core-design-principles)
- [The Two-Layer Architecture](#the-two-layer-architecture)
- [Implementation Details](#implementation-details)
- [Solving the Hard Problems](#solving-the-hard-problems)
- [Migration Plan (Fresh Start)](#migration-plan-fresh-start)
- [Code Structure](#code-structure)
- [Why This Wins](#why-this-wins)
- [Potential Gotchas & Solutions](#potential-gotchas--solutions)
- [The Payoff](#the-payoff)
- [Next Steps](#next-steps)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Use the mandated H2 heading for the Table of Contents

Please change the “Table of Contents” label to a ## Table of Contents heading to satisfy the docs guideline.

-Table of Contents
+## Table of Contents
📝 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.

Suggested change
Table of Contents
- [Executive Summary](#executive-summary)
- [Core Design Principles](#core-design-principles)
- [The Two-Layer Architecture](#the-two-layer-architecture)
- [Implementation Details](#implementation-details)
- [Solving the Hard Problems](#solving-the-hard-problems)
- [Migration Plan (Fresh Start)](#migration-plan-fresh-start)
- [Code Structure](#code-structure)
- [Why This Wins](#why-this-wins)
- [Potential Gotchas & Solutions](#potential-gotchas--solutions)
- [The Payoff](#the-payoff)
- [Next Steps](#next-steps)
## Table of Contents
- [Executive Summary](#executive-summary)
- [Core Design Principles](#core-design-principles)
- [The Two-Layer Architecture](#the-two-layer-architecture)
- [Implementation Details](#implementation-details)
- [Solving the Hard Problems](#solving-the-hard-problems)
- [Migration Plan (Fresh Start)](#migration-plan-fresh-start)
- [Code Structure](#code-structure)
- [Why This Wins](#why-this-wins)
- [Potential Gotchas & Solutions](#potential-gotchas--solutions)
- [The Payoff](#the-payoff)
- [Next Steps](#next-steps)
🤖 Prompt for AI Agents
In docs/architecture/journal-architecture.md around lines 15 to 28 the plain
text "Table of Contents" needs to be converted into a level-2 Markdown heading;
replace the current label with "## Table of Contents" (i.e., prepend "## " and
ensure it's on its own line) so the document follows the mandated H2 heading
guideline for the table of contents.

Comment on lines +1 to +9
---
title: Ref Name Validation
description: Building refs safely with Git-style branch shorthands.
audience: [contributors, developers]
domain: [architecture]
tags: [git, refs]
status: stable
last_updated: 2025-09-30
---

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add the required SPDX comment after front matter

Docs must include the license/SPDX comment immediately after the YAML front matter. Please add it here to satisfy the doc guidelines.

 ---
 title: Ref Name Validation
 description: Building refs safely with Git-style branch shorthands.
 audience: [contributors, developers]
 domain: [architecture]
 tags: [git, refs]
 status: stable
 last_updated: 2025-09-30
 ---
+<!-- SPDX-License-Identifier: Apache-2.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.

Suggested change
---
title: Ref Name Validation
description: Building refs safely with Git-style branch shorthands.
audience: [contributors, developers]
domain: [architecture]
tags: [git, refs]
status: stable
last_updated: 2025-09-30
---
---
title: Ref Name Validation
description: Building refs safely with Git-style branch shorthands.
audience: [contributors, developers]
domain: [architecture]
tags: [git, refs]
status: stable
last_updated: 2025-09-30
---
<!-- SPDX-License-Identifier: Apache-2.0 -->
🤖 Prompt for AI Agents
In docs/architecture/ref-name-validation.md around lines 1 to 9, the YAML front
matter is present but the required SPDX license comment is missing immediately
after the front matter; add the SPDX identifier comment line (e.g., "//
SPDX-License-Identifier: <LICENSE-ID>" or the project’s canonical SPDX comment
format) directly below the closing "---" of the front matter so the file
contains the license/SPDX comment immediately after the YAML block per doc
guidelines.

Comment on lines +1 to +9
---
title: System Architecture
description: High-level view of git-mind components and interactions.
audience: [developers]
domain: [architecture]
tags: [system, overview]
status: draft
last_updated: 2025-09-15
---

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Insert SPDX notice after the front matter

Per the docs guidelines, place the SPDX/license comment immediately after the YAML header.

 ---
 title: System Architecture
 description: High-level view of git-mind components and interactions.
 audience: [developers]
 domain: [architecture]
 tags: [system, overview]
 status: draft
 last_updated: 2025-09-15
 ---
+<!-- SPDX-License-Identifier: Apache-2.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.

Suggested change
---
title: System Architecture
description: High-level view of git-mind components and interactions.
audience: [developers]
domain: [architecture]
tags: [system, overview]
status: draft
last_updated: 2025-09-15
---
---
title: System Architecture
description: High-level view of git-mind components and interactions.
audience: [developers]
domain: [architecture]
tags: [system, overview]
status: draft
last_updated: 2025-09-15
---
<!-- SPDX-License-Identifier: Apache-2.0 -->
🤖 Prompt for AI Agents
In docs/architecture/system-overview.md around lines 1–9 the YAML front matter
is present but missing the required SPDX/license notice; add the SPDX license
comment immediately after the closing --- of the front matter by inserting the
project's SPDX identifier as a comment (e.g. an HTML or Markdown comment
containing "SPDX-License-Identifier: <identifier>") directly after the header
end so the notice is the first thing after the YAML block.

Comment on lines +13 to +20
Table of Contents

- [Executive Summary](#executive-summary)
- [High-Level Design](#high-level-design)
- [Components and Technology Stack](#components-and-technology-stack)
- [Data Flows and Storage](#data-flows-and-storage)
- [Scaling Strategy and Performance Targets](#scaling-strategy-and-performance-targets)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Promote “Table of Contents” to an H2 heading

Docs must include a ## Table of Contents section. Please update the heading accordingly.

-Table of Contents
+## Table of Contents
📝 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.

Suggested change
Table of Contents
- [Executive Summary](#executive-summary)
- [High-Level Design](#high-level-design)
- [Components and Technology Stack](#components-and-technology-stack)
- [Data Flows and Storage](#data-flows-and-storage)
- [Scaling Strategy and Performance Targets](#scaling-strategy-and-performance-targets)
## Table of Contents
- [Executive Summary](#executive-summary)
- [High-Level Design](#high-level-design)
- [Components and Technology Stack](#components-and-technology-stack)
- [Data Flows and Storage](#data-flows-and-storage)
- [Scaling Strategy and Performance Targets](#scaling-strategy-and-performance-targets)
🤖 Prompt for AI Agents
In docs/architecture/system-overview.md around lines 13 to 20, the "Table of
Contents" text is plain text but should be an H2 heading; change the line to use
Markdown H2 syntax ("## Table of Contents") so the docs include the required
section header and render correctly in the table of contents.

Comment on lines +1 to +10
---
title: 0d1b34b0ee501bc7b7b2d0a9fb82e06a37642c77.md
description: Preserved review artifacts and rationale.
audience: [contributors]
domain: [quality]
tags: [review]
status: archive
---

# Code Review Feedback

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Doc header must match guidelines.

The front matter title must be "Code Review Feedback" (matching the H1), the SPDX/license comment must appear immediately after the front matter, and a "## Table of Contents" section must follow the H1.

Apply this diff:

 ---
-title: 0d1b34b0ee501bc7b7b2d0a9fb82e06a37642c77.md
+title: Code Review Feedback
 description: Preserved review artifacts and rationale.
 audience: [contributors]
 domain: [quality]
 tags: [review]
 status: archive
 ---
+<!-- SPDX-License-Identifier: LicenseRef-MIND-UCAL-1.0 -->
+<!-- © 2025 J. Kirby Ross / Neuroglyph Collective -->
 
 # Code Review Feedback
+
+## Table of Contents

As per coding guidelines.

📝 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.

Suggested change
---
title: 0d1b34b0ee501bc7b7b2d0a9fb82e06a37642c77.md
description: Preserved review artifacts and rationale.
audience: [contributors]
domain: [quality]
tags: [review]
status: archive
---
# Code Review Feedback
---
title: Code Review Feedback
description: Preserved review artifacts and rationale.
audience: [contributors]
domain: [quality]
tags: [review]
status: archive
---
<!-- SPDX-License-Identifier: LicenseRef-MIND-UCAL-1.0 -->
<!-- © 2025 J. Kirby Ross / Neuroglyph Collective -->
# Code Review Feedback
## Table of Contents

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f33dfc0 and 0a5ece9.

📒 Files selected for processing (3)
  • AGENTS.md (1 hunks)
  • docs/code-reviews/PR177/9f49dd2ad65837735ac218c3d159b36f8b840819.md (1 hunks)
  • docs/operations/Telemetry_Config.md (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • docs/operations/Telemetry_Config.md
🧰 Additional context used
📓 Path-based instructions (1)
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.md: Docs must have front matter first, a single H1, a '## Table of Contents', and the title must match the H1
Add api_version field to API docs front matter
Place License/SPDX comments immediately after front matter in docs
README and other Markdown must comply with markdownlint rules: underscore emphasis/strong, blockquote spacing, code fence formatting, no inline HTML wrappers, heading punctuation

Files:

  • docs/code-reviews/PR177/9f49dd2ad65837735ac218c3d159b36f8b840819.md

Comment on lines +1 to +18
---
title: 9f49dd2ad65837735ac218c3d159b36f8b840819.md
description: Preserved review artifacts and rationale.
audience: [contributors]
domain: [quality]
tags: [review]
status: archive
---

# Code Review Feedback

| Date | Agent | SHA | Branch | PR |
|------|-------|-----|--------|----|
| 2025-10-08 | CodeRabbit (and reviewers) | `9f49dd2ad65837735ac218c3d159b36f8b840819` | [feat/hex-ports-ci-green](https://github.com/neuroglyph/git-mind/tree/feat/hex-ports-ci-green "neuroglyph/git-mind:feat/hex-ports-ci-green") | [PR#177](https://github.com/neuroglyph/git-mind/pull/177) |

## CODE REVIEW FEEDBACK

### core/src/adapters/logging/stdio_logger_adapter.c:41 — coderabbitai[bot]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Align front matter with doc standards.

Please update the front matter title to match the H1, insert the required SPDX/license comments immediately after the front matter, and add the mandatory ## Table of Contents section. These steps are required for every docs/**/*.md file. As per coding guidelines

 ---
-title: 9f49dd2ad65837735ac218c3d159b36f8b840819.md
+title: Code Review Feedback
 description: Preserved review artifacts and rationale.
 audience: [contributors]
 domain: [quality]
 tags: [review]
 status: archive
 ---
+
+<!-- SPDX-License-Identifier: LicenseRef-MIND-UCAL-1.0 -->
+<!-- © 2025 J. Kirby Ross / Neuroglyph Collective -->
 
 # Code Review Feedback
+
+## Table of Contents
+
+- [Code Review Feedback](#code-review-feedback)
+- [CODE REVIEW FEEDBACK](#code-review-feedback-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.

Suggested change
---
title: 9f49dd2ad65837735ac218c3d159b36f8b840819.md
description: Preserved review artifacts and rationale.
audience: [contributors]
domain: [quality]
tags: [review]
status: archive
---
# Code Review Feedback
| Date | Agent | SHA | Branch | PR |
|------|-------|-----|--------|----|
| 2025-10-08 | CodeRabbit (and reviewers) | `9f49dd2ad65837735ac218c3d159b36f8b840819` | [feat/hex-ports-ci-green](https://github.com/neuroglyph/git-mind/tree/feat/hex-ports-ci-green "neuroglyph/git-mind:feat/hex-ports-ci-green") | [PR#177](https://github.com/neuroglyph/git-mind/pull/177) |
## CODE REVIEW FEEDBACK
### core/src/adapters/logging/stdio_logger_adapter.c:41 — coderabbitai[bot]
---
title: Code Review Feedback
description: Preserved review artifacts and rationale.
audience: [contributors]
domain: [quality]
tags: [review]
status: archive
---
<!-- SPDX-License-Identifier: LicenseRef-MIND-UCAL-1.0 -->
<!-- © 2025 J. Kirby Ross / Neuroglyph Collective -->
# Code Review Feedback
## Table of Contents
- [Code Review Feedback](#code-review-feedback)
- [CODE REVIEW FEEDBACK](#code-review-feedback-1)
| Date | Agent | SHA | Branch | PR |
|------|-------|-----|--------|----|
| 2025-10-08 | CodeRabbit (and reviewers) | `9f49dd2ad65837735ac218c3d159b36f8b840819` | [feat/hex-ports-ci-green](https://github.com/neuroglyph/git-mind/tree/feat/hex-ports-ci-green "neuroglyph/git-mind:feat/hex-ports-ci-green") | [PR#177](https://github.com/neuroglyph/git-mind/pull/177) |
## CODE REVIEW FEEDBACK
### core/src/adapters/logging/stdio_logger_adapter.c:41 — coderabbitai[bot]
🤖 Prompt for AI Agents
In docs/code-reviews/PR177/9f49dd2ad65837735ac218c3d159b36f8b840819.md lines
1-18, the front matter title doesn't match the H1 and the required SPDX/license
comment and Table of Contents section are missing; update the front matter title
to exactly match the H1, add the required SPDX/license comment block immediately
after the front matter, and insert a mandatory "## Table of Contents" heading
(with any needed anchors/placeholder entries) below the SPDX/license block so
the file conforms to docs/**/*.md standards.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 (2)
docs/README.md (2)

10-12: Add the required SPDX comment after the front matter.

Docs must place the SPDX/license comment immediately after the YAML front matter, but this file doesn’t. Add the project’s SPDX identifier comment right after the front matter block.


13-20: Promote “Table of Contents” to an H2 heading.

Documentation guidelines require a ## Table of Contents heading; this section is plain text. Update it to use the proper H2 heading.

♻️ Duplicate comments (1)
migration-progress.md (1)

1-5: Missing front matter (duplicate concern).

This issue has already been flagged in a previous review. The file is missing the required YAML front matter block at the beginning.

🧹 Nitpick comments (5)
AGENTS.md (1)

551-556: Approve with note on unconventional format.

The JSON activity logs are unusual for markdown documentation but appear intentional for structured, machine-parseable tracking. Consider documenting this format choice if it's part of a broader automation strategy.

core/tests/unit/test_cache_oid_prefix.c (1)

12-32: Consider documenting test cases.

The test validates OID prefix extraction at various bit lengths (4, 8, 12, 20), but the expected values and rationale aren't documented. Adding brief comments explaining the hex-to-prefix mapping would improve test maintainability.

Example:

+    /* 4 bits = 1 hex char → "0" */
     assert(gm_cache_oid_prefix(&oid, 4, out, sizeof(out)) == GM_OK);
     assert(strcmp(out, "0") == 0);
core/tests/fakes/metrics/fake_metrics_port.h (1)

16-23: Consider defining capacity constants.

The fake state struct uses magic numbers for array sizes (32 entries, 64-char names, 256-char tags). Defining named constants would improve readability and maintainability.

Example:

+#define GM_FAKE_METRICS_MAX_ENTRIES 32
+#define GM_FAKE_METRICS_NAME_SIZE 64
+#define GM_FAKE_METRICS_TAGS_SIZE 256
+
 typedef struct {
-    struct { char name[64]; uint64_t value; char tags[256]; } counters[32];
+    struct { char name[GM_FAKE_METRICS_NAME_SIZE]; uint64_t value; char tags[GM_FAKE_METRICS_TAGS_SIZE]; } counters[GM_FAKE_METRICS_MAX_ENTRIES];
core/tests/unit/test_telemetry_cfg.c (1)

14-24: Note on memory management in test helper.

The set_env helper allocates heap strings (line 20) that are never freed, causing a memory leak. This is acceptable for short-lived test processes that exit immediately after running tests, as putenv requires the string to persist for the process lifetime.

Consider adding a comment documenting this intentional leak:

+    /* Note: allocated string intentionally not freed; putenv requires it to persist */
     char *heap = (char *)malloc((size_t)n + 1);
core/tests/fakes/logging/fake_logger_port.h (1)

16-21: Consider defining capacity constants.

Similar to the metrics fake port, the logger state struct uses magic numbers for array sizes (32 entries, 32-char components, 256-char messages). Defining named constants would improve consistency across test fakes and maintainability.

Example:

+#define GM_FAKE_LOGGER_MAX_ENTRIES 32
+#define GM_FAKE_LOGGER_COMPONENT_SIZE 32
+#define GM_FAKE_LOGGER_MESSAGE_SIZE 256
+
 typedef struct {
-    gm_log_level_t level[32];
-    char component[32][32];
-    char message[32][256];
+    gm_log_level_t level[GM_FAKE_LOGGER_MAX_ENTRIES];
+    char component[GM_FAKE_LOGGER_MAX_ENTRIES][GM_FAKE_LOGGER_COMPONENT_SIZE];
+    char message[GM_FAKE_LOGGER_MAX_ENTRIES][GM_FAKE_LOGGER_MESSAGE_SIZE];
     size_t count;
 } gm_fake_logger_state_t;
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f7ec09 and 075026f.

📒 Files selected for processing (24)
  • AGENTS.md (4 hunks)
  • core/include/gitmind/cache/internal/oid_prefix.h (1 hunks)
  • core/include/gitmind/telemetry/internal/config.h (1 hunks)
  • core/src/app/cache/cache_rebuild_service.c (8 hunks)
  • core/src/domain/cache/oid_prefix.c (1 hunks)
  • core/src/telemetry/config.c (1 hunks)
  • core/tests/fakes/logging/fake_logger_port.c (1 hunks)
  • core/tests/fakes/logging/fake_logger_port.h (1 hunks)
  • core/tests/fakes/metrics/fake_metrics_port.c (1 hunks)
  • core/tests/fakes/metrics/fake_metrics_port.h (1 hunks)
  • core/tests/unit/test_cache_oid_prefix.c (1 hunks)
  • core/tests/unit/test_cache_telemetry_emit.c (1 hunks)
  • core/tests/unit/test_telemetry_cfg.c (1 hunks)
  • docs/README.md (1 hunks)
  • docs/cli/README.md (0 hunks)
  • docs/cli/combined_markdown.md (0 hunks)
  • docs/cli/gitmind-cache-rebuild.md (0 hunks)
  • docs/cli/gitmind-install-hooks.md (0 hunks)
  • docs/cli/gitmind-link.md (0 hunks)
  • docs/cli/gitmind-list.md (0 hunks)
  • docs/cli/gitmind.md (0 hunks)
  • docs/code-reviews/PR177/62e7ab80a904e1bc42f06c250efb102af17ea962.md (1 hunks)
  • meson.build (4 hunks)
  • migration-progress.md (1 hunks)
💤 Files with no reviewable changes (7)
  • docs/cli/gitmind-link.md
  • docs/cli/gitmind-cache-rebuild.md
  • docs/cli/combined_markdown.md
  • docs/cli/gitmind.md
  • docs/cli/gitmind-install-hooks.md
  • docs/cli/README.md
  • docs/cli/gitmind-list.md
🧰 Additional context used
📓 Path-based instructions (12)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use NOLINT to suppress clang-tidy warnings; ALWAYS fix the underlying issue

Files:

  • core/tests/fakes/metrics/fake_metrics_port.h
  • core/tests/unit/test_cache_oid_prefix.c
  • core/tests/unit/test_telemetry_cfg.c
  • core/tests/unit/test_cache_telemetry_emit.c
  • core/include/gitmind/cache/internal/oid_prefix.h
  • core/tests/fakes/logging/fake_logger_port.h
  • core/src/telemetry/config.c
  • core/include/gitmind/telemetry/internal/config.h
  • core/src/app/cache/cache_rebuild_service.c
  • core/tests/fakes/logging/fake_logger_port.c
  • core/src/domain/cache/oid_prefix.c
  • core/tests/fakes/metrics/fake_metrics_port.c
{core,src,apps,tests}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

{core,src,apps,tests}/**/*.{c,h}: Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths
Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required
Equality is OID-first; if both OIDs exist they must match; only fall back to SHA when OIDs are absent
Build refs via gm_build_ref and reject inputs that start with "refs/"
Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes
Formatting via .clang-format (LLVM style, 4 spaces, 80 cols, pointer alignment right); pre-commit runs clang-format
Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with t; header guards start with GITMIND
Includes: prefer specific headers; order/regroup per .clang-format; include-what-you-use
No new clang-tidy warnings; keep touched files tidy-clean
Surface failures via gm_result_t (and variants); ports must not return raw integers
Maintain one responsibility per translation unit where practical; split multi-concern files when touched
Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers
Zero output buffers before formatting/copying on error paths

Files:

  • core/tests/fakes/metrics/fake_metrics_port.h
  • core/tests/unit/test_cache_oid_prefix.c
  • core/tests/unit/test_telemetry_cfg.c
  • core/tests/unit/test_cache_telemetry_emit.c
  • core/include/gitmind/cache/internal/oid_prefix.h
  • core/tests/fakes/logging/fake_logger_port.h
  • core/src/telemetry/config.c
  • core/include/gitmind/telemetry/internal/config.h
  • core/src/app/cache/cache_rebuild_service.c
  • core/tests/fakes/logging/fake_logger_port.c
  • core/src/domain/cache/oid_prefix.c
  • core/tests/fakes/metrics/fake_metrics_port.c
core/tests/fakes/**

📄 CodeRabbit inference engine (AGENTS.md)

Provide deterministic fakes/mocks/stubs for every outbound port under core/tests/fakes/** with harnesses verifying contract invariants

Files:

  • core/tests/fakes/metrics/fake_metrics_port.h
  • core/tests/fakes/logging/fake_logger_port.h
  • core/tests/fakes/logging/fake_logger_port.c
  • core/tests/fakes/metrics/fake_metrics_port.c
core/tests/unit/test_*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests live in core/tests/unit/ and are named test_.c; keep deterministic and isolated

Files:

  • core/tests/unit/test_cache_oid_prefix.c
  • core/tests/unit/test_telemetry_cfg.c
  • core/tests/unit/test_cache_telemetry_emit.c
core/tests/**/*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests should use fakes only; integration tests may use real adapters but only inside Docker

Files:

  • core/tests/unit/test_cache_oid_prefix.c
  • core/tests/unit/test_telemetry_cfg.c
  • core/tests/unit/test_cache_telemetry_emit.c
  • core/tests/fakes/logging/fake_logger_port.c
  • core/tests/fakes/metrics/fake_metrics_port.c
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.md: Docs must have front matter first, a single H1, a '## Table of Contents', and the title must match the H1
Add api_version field to API docs front matter
Place License/SPDX comments immediately after front matter in docs
README and other Markdown must comply with markdownlint rules: underscore emphasis/strong, blockquote spacing, code fence formatting, no inline HTML wrappers, heading punctuation

Files:

  • docs/README.md
  • docs/code-reviews/PR177/62e7ab80a904e1bc42f06c250efb102af17ea962.md
core/include/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public headers under core/include must be umbrella-safe: compile standalone, include only what they use, stable header guards, and provide extern "C" when included from C++

Files:

  • core/include/gitmind/cache/internal/oid_prefix.h
  • core/include/gitmind/telemetry/internal/config.h
core/include/gitmind/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public structs in headers must avoid ABI breaks; append new fields at the struct tail and mark deprecated fields instead of removing

Files:

  • core/include/gitmind/cache/internal/oid_prefix.h
  • core/include/gitmind/telemetry/internal/config.h
meson.build

📄 CodeRabbit inference engine (AGENTS.md)

Target C23 via Meson c2x and keep warnings-as-errors; register new unit test targets in meson.build

Files:

  • meson.build
core/src/**/{hooks,cache,journal}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid direct libgit2 usage; route repository/ref operations through gm_git_repository_port/gm_git_ref_port adapters

Files:

  • core/src/app/cache/cache_rebuild_service.c
  • core/src/domain/cache/oid_prefix.c
core/src/domain/**

📄 CodeRabbit inference engine (AGENTS.md)

Domain core code under core/src/domain/** must be pure/deterministic (no direct IO/libgit2/global state)

Files:

  • core/src/domain/cache/oid_prefix.c
core/src/domain/{edge,journal,cache,attribution,hooks}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

Wrap all side effects behind outbound ports; no direct IO or libgit2 in domain modules

Files:

  • core/src/domain/cache/oid_prefix.c
🧠 Learnings (16)
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to docs/activity/**/*.md : Document migration progress and lessons under docs/activity/<date>_hexagonal.md

Applied to files:

  • migration-progress.md
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to docs/architecture/hexagonal/** : Track adapter status and migrations in docs/architecture/hexagonal/**; keep diagrams and status tables updated

Applied to files:

  • migration-progress.md
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers

Applied to files:

  • core/include/gitmind/cache/internal/oid_prefix.h
  • core/src/app/cache/cache_rebuild_service.c
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to core/include/gitmind/ports/**/*.h : Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

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: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h

Applied to files:

  • meson.build
  • 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: Applies to include/gitmind/**/*.h : Public, namespaced headers live under include/gitmind/

Applied to files:

  • meson.build
  • AGENTS.md
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with _t; header guards start with GITMIND_

Applied to files:

  • AGENTS.md
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{h} : Header guards must be stable and named GITMIND_*; add extern "C" guards for C++ consumers in public headers

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: Applies to {core,include}/**/*.{c,h} : Language: C23 with warnings-as-errors; no VLAs; no variable shadowing; use explicit prototypes

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: Applies to {include,core/include}/**/*.h : Header guards use GITMIND_* naming

Applied to files:

  • AGENTS.md
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes

Applied to files:

  • AGENTS.md
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to include/**/*.h : Umbrella API headers (include/gitmind.h and include/gitmind/**) must be umbrella-safe and carry extern "C" guards for C++

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: 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:

  • AGENTS.md
📚 Learning: 2025-09-14T09:27:33.283Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-14T09:27:33.283Z
Learning: Applies to **/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm} : NEVER use `NOLINT` to suppress clang-tidy warnings; ALWAYS fix the underlying issue

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: Conventional commits (type(scope): description) and reference issues; PRs must describe changes, link issues, include test plan, and update docs when applicable

Applied to files:

  • AGENTS.md
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Maintain one responsibility per translation unit where practical; split multi-concern files when touched

Applied to files:

  • AGENTS.md
🧬 Code graph analysis (8)
core/tests/fakes/metrics/fake_metrics_port.h (1)
core/tests/fakes/metrics/fake_metrics_port.c (2)
  • gm_fake_metrics_port_init (60-73)
  • gm_fake_metrics_port_dispose (75-80)
core/tests/unit/test_cache_telemetry_emit.c (6)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/include/gitmind/security/memory.h (1)
  • gm_memset_safe (47-59)
core/tests/fakes/logging/fake_logger_port.c (2)
  • gm_fake_logger_port_init (31-46)
  • gm_fake_logger_port_dispose (48-53)
core/tests/fakes/metrics/fake_metrics_port.c (2)
  • gm_fake_metrics_port_init (60-73)
  • gm_fake_metrics_port_dispose (75-80)
core/src/app/cache/cache_rebuild_service.c (1)
  • gm_cache_rebuild_execute (476-623)
core/tests/fakes/fs/fake_fs_temp_port.c (1)
  • gm_fake_fs_temp_port_dispose (252-259)
core/include/gitmind/cache/internal/oid_prefix.h (1)
core/src/domain/cache/oid_prefix.c (1)
  • int (13-44)
core/tests/fakes/logging/fake_logger_port.h (1)
core/tests/fakes/logging/fake_logger_port.c (2)
  • gm_fake_logger_port_init (31-46)
  • gm_fake_logger_port_dispose (48-53)
core/src/telemetry/config.c (1)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/src/app/cache/cache_rebuild_service.c (3)
core/include/gitmind/ports/logger_port.h (1)
  • gm_logger_log (66-74)
core/include/gitmind/ports/metrics_port.h (3)
  • gm_metrics_timing_ms (72-79)
  • gm_metrics_counter_add (52-59)
  • gm_metrics_gauge_set (62-69)
core/src/error/error.c (1)
  • gm_error_free (161-178)
core/tests/fakes/logging/fake_logger_port.c (1)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/tests/fakes/metrics/fake_metrics_port.c (1)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
🔇 Additional comments (8)
AGENTS.md (3)

129-129: LGTM!

The explicit ban on NOLINT usage is consistent with the coding guidelines and ensures that all warnings are addressed rather than suppressed.


142-149: LGTM!

The added git workflow guardrails properly emphasize intentional staging and forbid circumventing hooks or tests, which helps maintain code quality and repository integrity.


397-400: LGTM!

The integration of legacy security and memory safety concerns into the hexagonal architecture framework ensures that these critical aspects are addressed during module migrations.

core/tests/fakes/logging/fake_logger_port.c (2)

13-25: LGTM with note on truncation handling.

The implementation correctly uses gm_strcpy_safe for string operations and intentionally ignores truncation (via (void) casts). This is acceptable for test fakes where silent truncation is preferable to test failures.


31-53: LGTM!

The init and dispose functions properly handle NULL checks, allocation failures, and cleanup. Error codes are appropriate and memory management is correct.

core/tests/unit/test_telemetry_cfg.c (1)

26-98: LGTM!

The test functions comprehensively validate telemetry configuration loading, extras handling, and repository tagging. Assertions are appropriate and test coverage is thorough.

core/include/gitmind/cache/internal/oid_prefix.h (1)

1-31: LGTM!

The header is well-structured with proper guards, clear documentation, and correct use of GM_NODISCARD. The API is concise and follows project conventions.

meson.build (1)

124-125: LGTM! Build system changes are complete and consistent.

All new source files (domain helpers, telemetry config, cache ports, adapters), test executables with proper fakes, test registrations, and public header exposures are correctly added and align with the PR objectives.

Also applies to: 131-132, 140-141, 374-393, 429-431, 448-451

Comment thread core/src/app/cache/cache_rebuild_service.c
Comment thread core/src/telemetry/config.c Outdated
Comment thread core/tests/fakes/metrics/fake_metrics_port.c
Comment thread core/tests/unit/test_cache_telemetry_emit.c
Comment thread core/tests/unit/test_cache_telemetry_emit.c
Comment thread docs/code-reviews/PR177/62e7ab80a904e1bc42f06c250efb102af17ea962.md Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (1)
core/tests/unit/test_repo_build_tree.c (1)

66-72: Clean up created test directories.

The test creates .gm_build_tree_repo and .gm_build_tree_src directories but never removes them. Add cleanup to prevent accumulating test artifacts across runs.

Consider adding cleanup after line 71:

    git_repository_free(repo);
    git_libgit2_shutdown();
+   // Clean up test directories
+   system("rm -rf .gm_build_tree_repo .gm_build_tree_src");
    printf("OK\n");
    return 0;

Note: Alternatively, use a more robust cleanup approach with proper error handling, or rely on the test harness to clean up ephemeral directories.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 075026f and 12f7afd.

📒 Files selected for processing (3)
  • core/tests/unit/test_repo_build_tree.c (1 hunks)
  • docs/code-reviews/PR177/191912ae67648beab20b6c597cc130e73db5a1e5.md (1 hunks)
  • meson.build (5 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use NOLINT to suppress clang-tidy warnings; ALWAYS fix the underlying issue

Files:

  • core/tests/unit/test_repo_build_tree.c
{core,src,apps,tests}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

{core,src,apps,tests}/**/*.{c,h}: Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths
Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required
Equality is OID-first; if both OIDs exist they must match; only fall back to SHA when OIDs are absent
Build refs via gm_build_ref and reject inputs that start with "refs/"
Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes
Formatting via .clang-format (LLVM style, 4 spaces, 80 cols, pointer alignment right); pre-commit runs clang-format
Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with t; header guards start with GITMIND
Includes: prefer specific headers; order/regroup per .clang-format; include-what-you-use
No new clang-tidy warnings; keep touched files tidy-clean
Surface failures via gm_result_t (and variants); ports must not return raw integers
Maintain one responsibility per translation unit where practical; split multi-concern files when touched
Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers
Zero output buffers before formatting/copying on error paths

Files:

  • core/tests/unit/test_repo_build_tree.c
core/tests/unit/test_*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests live in core/tests/unit/ and are named test_.c; keep deterministic and isolated

Files:

  • core/tests/unit/test_repo_build_tree.c
core/tests/**/*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests should use fakes only; integration tests may use real adapters but only inside Docker

Files:

  • core/tests/unit/test_repo_build_tree.c
meson.build

📄 CodeRabbit inference engine (AGENTS.md)

Target C23 via Meson c2x and keep warnings-as-errors; register new unit test targets in meson.build

Files:

  • meson.build
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.md: Docs must have front matter first, a single H1, a '## Table of Contents', and the title must match the H1
Add api_version field to API docs front matter
Place License/SPDX comments immediately after front matter in docs
README and other Markdown must comply with markdownlint rules: underscore emphasis/strong, blockquote spacing, code fence formatting, no inline HTML wrappers, heading punctuation

Files:

  • docs/code-reviews/PR177/191912ae67648beab20b6c597cc130e73db5a1e5.md
🧠 Learnings (3)
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to core/include/gitmind/ports/**/*.h : Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

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: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h

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: Applies to include/gitmind/**/*.h : Public, namespaced headers live under include/gitmind/

Applied to files:

  • meson.build
🔇 Additional comments (2)
meson.build (2)

357-361: Verify test categorization aligns with test type.

test_repo_build_tree uses real libgit2 adapters (see the test source review), making it an integration test rather than a unit test. If the test is moved to the integration test directory as suggested in the file review, update the executable path here and consider whether it needs different test registration flags or environment setup (e.g., Docker-only execution).

The build configuration looks correct for the current location. Coordinate changes with test relocation.

Also applies to: 431-431


455-458: LGTM: New port headers properly exposed.

The new public port headers (logger_port.h, metrics_port.h, cache_build_port.h, cache_query_port.h) are correctly placed under core/include/gitmind/ports/ and registered for compilation checks. This aligns with the learnings about defining ports as headers under core/include/gitmind/ports/**.

Based on learnings.

Comment thread core/tests/unit/test_repo_build_tree.c Outdated
Comment thread core/tests/unit/test_repo_build_tree.c Outdated
Comment thread docs/code-reviews/PR177/191912ae67648beab20b6c597cc130e73db5a1e5.md Outdated
flyingrobots and others added 3 commits October 8, 2025 00:55
…SH_ALGO=sha256|fnv); update docs with custom logger adapter guidance; tests exercise sha256 path; CI green

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
core/src/telemetry/config.c (1)

255-255: Check gm_strcpy_safe return value and handle truncation.

The (void) cast ignores truncation when copying repo_canon_path, which could be longer than the 65-byte repo_val buffer. Per coding guidelines, truncation must be treated as an error.

Apply this fix:

         if (cfg->repo_tag == GM_REPO_TAG_PLAIN) {
             if (repo_canon_path != NULL && repo_canon_path[0] != '\0') {
-                (void)gm_strcpy_safe(repo_val, sizeof(repo_val), repo_canon_path);
+                if (gm_strcpy_safe(repo_val, sizeof(repo_val), repo_canon_path) != 0) {
+                    return gm_err_void(GM_ERROR(GM_ERR_BUFFER_TOO_SMALL, "repo path too long"));
+                }
             }

As per coding guidelines.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 12f7afd and 74e0f06.

📒 Files selected for processing (4)
  • core/include/gitmind/telemetry/internal/config.h (1 hunks)
  • core/src/telemetry/config.c (1 hunks)
  • core/tests/unit/test_telemetry_cfg.c (1 hunks)
  • docs/operations/Telemetry_Config.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/include/gitmind/telemetry/internal/config.h
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use NOLINT to suppress clang-tidy warnings; ALWAYS fix the underlying issue

Files:

  • core/tests/unit/test_telemetry_cfg.c
  • core/src/telemetry/config.c
{core,src,apps,tests}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

{core,src,apps,tests}/**/*.{c,h}: Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths
Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required
Equality is OID-first; if both OIDs exist they must match; only fall back to SHA when OIDs are absent
Build refs via gm_build_ref and reject inputs that start with "refs/"
Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes
Formatting via .clang-format (LLVM style, 4 spaces, 80 cols, pointer alignment right); pre-commit runs clang-format
Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with t; header guards start with GITMIND
Includes: prefer specific headers; order/regroup per .clang-format; include-what-you-use
No new clang-tidy warnings; keep touched files tidy-clean
Surface failures via gm_result_t (and variants); ports must not return raw integers
Maintain one responsibility per translation unit where practical; split multi-concern files when touched
Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers
Zero output buffers before formatting/copying on error paths

Files:

  • core/tests/unit/test_telemetry_cfg.c
  • core/src/telemetry/config.c
core/tests/unit/test_*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests live in core/tests/unit/ and are named test_.c; keep deterministic and isolated

Files:

  • core/tests/unit/test_telemetry_cfg.c
core/tests/**/*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests should use fakes only; integration tests may use real adapters but only inside Docker

Files:

  • core/tests/unit/test_telemetry_cfg.c
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.md: Docs must have front matter first, a single H1, a '## Table of Contents', and the title must match the H1
Add api_version field to API docs front matter
Place License/SPDX comments immediately after front matter in docs
README and other Markdown must comply with markdownlint rules: underscore emphasis/strong, blockquote spacing, code fence formatting, no inline HTML wrappers, heading punctuation

Files:

  • docs/operations/Telemetry_Config.md
🧠 Learnings (2)
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths

Applied to files:

  • core/src/telemetry/config.c
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required

Applied to files:

  • core/src/telemetry/config.c
🧬 Code graph analysis (2)
core/tests/unit/test_telemetry_cfg.c (1)
core/tests/unit/test_cache_telemetry_emit.c (1)
  • set_env (110-119)
core/src/telemetry/config.c (4)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/src/crypto/backend.c (2)
  • gm_crypto_context_create (81-99)
  • gm_crypto_backend_libsodium (75-77)
core/src/crypto/sha256.c (1)
  • gm_sha256_with_context (19-37)
core/src/error/error.c (1)
  • gm_error_free (161-178)
🔇 Additional comments (11)
core/src/telemetry/config.c (5)

23-61: LGTM! Parsing helpers are defensive and sensible.

The parsing helpers handle null/empty inputs gracefully with appropriate defaults, use case-insensitive string comparison, and provide sensible fallback values for unrecognized inputs.


63-93: LGTM! Character and key/value validation are appropriately defensive.

The validation helpers use conservative character sets for keys and values, properly check lengths against struct field sizes, and reject null/empty inputs where appropriate.


136-179: LGTM! Config loading is properly implemented.

The function validates inputs, initializes sensible defaults, reads environment variables through the port abstraction, and returns appropriate results.


181-225: LGTM! Tag building helpers are correctly implemented.

The helpers properly:

  • Check buffer overflow in append_kv using gm_snprintf return value
  • Implement standard FNV-1a hashing in fnv1a64_hex12
  • Handle crypto backend errors gracefully in sha256_hex12, freeing error structures before falling back to FNV

227-301: Tag building logic is sound beyond the truncation issue.

The function properly validates inputs, respects configuration flags, handles multiple tag sources (branch, mode, repo, extras), enforces the total tag limit, and returns appropriate overflow errors.

docs/operations/Telemetry_Config.md (1)

16-141: LGTM! Telemetry configuration documentation is comprehensive and well-structured.

The document provides clear guidance on:

  • Safe defaults and customization boundaries
  • Environment variable knobs with descriptions
  • Guardrails for preventing high-cardinality issues
  • Implementation plan and examples
  • Extension points for custom adapters

The content aligns well with the code changes in core/src/telemetry/config.c and core/include/gitmind/telemetry/internal/config.h.

core/tests/unit/test_telemetry_cfg.c (5)

14-24: LGTM! Portable environment helper is correctly implemented.

The set_env function allocates heap strings for putenv as required by POSIX. The memory leak is acceptable in test code, as the strings must persist for the process lifetime.


26-49: LGTM! Default configuration test validates expected behavior.

The test properly:

  • Clears all environment variables to ensure defaults
  • Loads configuration and asserts default values
  • Builds tags with branch and mode
  • Verifies the expected tag string format

51-73: LGTM! Extras parsing test covers validation and capacity limits.

The test verifies:

  • Valid extras are parsed and added (team, role)
  • Invalid entries are dropped (space in key)
  • Capacity limits are enforced (max 3 extras)
  • The extras_dropped flag is set appropriately
  • All expected tags appear in the output

75-92: LGTM! Repo hash test validates tag generation from repo ID.

The test confirms:

  • Repo tag mode is configured from environment
  • Hash algorithm selection works (SHA256)
  • Tags are built from repo ID when path is absent
  • The repo tag appears in the output along with branch and mode

94-99: LGTM! Test suite is properly structured.

The main function executes all tests in sequence and returns success.

Comment thread core/src/telemetry/config.c Outdated
Comment thread docs/operations/Telemetry_Config.md
flyingrobots and others added 3 commits October 8, 2025 01:55
…n) + default renderer; refactor cache service to use it; add unit tests; docs/telemetry updated; CI green

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
core/src/app/cache/cache_rebuild_service.c (1)

494-520: Honor gm_telemetry_ return values to avoid leaked errors.*

Both gm_telemetry_cfg_load and gm_telemetry_build_tags return gm_result_void_t, yet their results are cast to void. If either surfaces an error, the gm_error_t leaks and we proceed with possibly uninitialized config/tag buffers. Please capture the results, free any error payloads, and decide whether to continue (with defaults) or abort.

As per coding guidelines

Apply this diff:

-    gm_telemetry_cfg_t tcfg = {0};
-    (void)gm_telemetry_cfg_load(&tcfg, gm_env_port_system());
+    gm_telemetry_cfg_t tcfg = {0};
+    gm_result_void_t cfg_rc =
+        gm_telemetry_cfg_load(&tcfg, gm_env_port_system());
+    if (!cfg_rc.ok) {
+        if (cfg_rc.u.err != NULL) {
+            gm_error_free(cfg_rc.u.err);
+        }
+        /* Defaults in tcfg stay zeroed; continue without telemetry tweaks. */
+    }
@@
-    (void)gm_telemetry_build_tags(&tcfg, branch, mode, repo_canon, &repo_id,
-                                  tags, sizeof(tags));
+    gm_result_void_t tags_rc = gm_telemetry_build_tags(
+        &tcfg, branch, mode, repo_canon, &repo_id, tags, sizeof(tags));
+    if (!tags_rc.ok) {
+        if (tags_rc.u.err != NULL) {
+            gm_error_free(tags_rc.u.err);
+        }
+        tags[0] = '\0';
+    }
🧹 Nitpick comments (3)
core/src/app/cache/cache_rebuild_service.c (2)

523-535: Check log formatter return to handle buffer overflow.

The log formatter can fail with GM_ERR_BUFFER_TOO_SMALL if the message buffer is insufficient. While telemetry is best-effort, checking the return allows you to truncate gracefully or skip the log rather than emitting potentially malformed output.

As per coding guidelines

Apply this diff:

     gm_log_formatter_fn fmt = ctx->log_formatter ? ctx->log_formatter
                                                  : gm_log_format_render_default;
-    (void)fmt(kvs, sizeof(kvs) / sizeof(kvs[0]),
-              (tcfg.log_format == GM_LOG_FMT_JSON), msg, sizeof(msg));
-    (void)gm_logger_log(&ctx->logger_port, GM_LOG_INFO, "cache", msg);
+    gm_result_void_t fmt_rc = fmt(kvs, sizeof(kvs) / sizeof(kvs[0]),
+                                   (tcfg.log_format == GM_LOG_FMT_JSON), msg, sizeof(msg));
+    if (fmt_rc.ok) {
+        (void)gm_logger_log(&ctx->logger_port, GM_LOG_INFO, "cache", msg);
+    } else if (fmt_rc.u.err != NULL) {
+        gm_error_free(fmt_rc.u.err);
+    }

602-622: Consider checking log formatter returns for consistency.

Similar to the rebuild_start logging, these success and failure log paths ignore the formatter return value. While best-effort telemetry is acceptable, checking the return ensures consistent error handling across all telemetry call sites.

Apply similar error handling as suggested for lines 523-535 to both the rebuild_ok and rebuild_failed logging blocks.

Also applies to: 626-641

core/tests/unit/test_log_formatter.c (1)

10-46: Consider expanding test coverage for error paths and edge cases.

The current tests validate happy paths for text and JSON rendering, which is a good start. However, consider adding tests for:

  • Error conditions: buffer too small, null output buffer, null kvs with non-zero count
  • Edge cases: empty kvs array (kv_count=0), null or empty keys/values, special characters requiring escaping (quotes, backslashes, control characters)
  • Boundary conditions: exactly-sized buffers, off-by-one scenarios

These additional tests would improve robustness and catch potential regressions.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 74e0f06 and e36b172.

📒 Files selected for processing (14)
  • core/include/gitmind/context.h (2 hunks)
  • core/include/gitmind/telemetry/internal/log_format.h (1 hunks)
  • core/src/app/cache/cache_rebuild_service.c (8 hunks)
  • core/src/telemetry/log_format.c (1 hunks)
  • core/tests/unit/test_log_formatter.c (1 hunks)
  • docs/code-reviews/PR173/17ddad1aa3747f40ecacc0bd202e7b83edbf1d1d.md (0 hunks)
  • docs/code-reviews/PR173/7445bcf00c71b6f768e9eb6b1fd99d2b1c60783f.md (0 hunks)
  • docs/code-reviews/PR173/e0243058aac14ff3a8c83af2f6d4dcfe97dd2804.md (0 hunks)
  • docs/code-reviews/PR174/bc1fc319303bf1a00b43b03a40992ba788996b1a.md (0 hunks)
  • docs/code-reviews/PR176/d4a10748b38ad2be13f639288bd14eaee0cf89dc.md (0 hunks)
  • docs/code-reviews/PR176/ecc3e4ac371ce646fd9a31573000ab4599d8f7ab.md (0 hunks)
  • docs/operations/Telemetry_Config.md (1 hunks)
  • meson.build (6 hunks)
  • migration-progress.md (1 hunks)
💤 Files with no reviewable changes (6)
  • docs/code-reviews/PR173/7445bcf00c71b6f768e9eb6b1fd99d2b1c60783f.md
  • docs/code-reviews/PR173/17ddad1aa3747f40ecacc0bd202e7b83edbf1d1d.md
  • docs/code-reviews/PR176/d4a10748b38ad2be13f639288bd14eaee0cf89dc.md
  • docs/code-reviews/PR174/bc1fc319303bf1a00b43b03a40992ba788996b1a.md
  • docs/code-reviews/PR176/ecc3e4ac371ce646fd9a31573000ab4599d8f7ab.md
  • docs/code-reviews/PR173/e0243058aac14ff3a8c83af2f6d4dcfe97dd2804.md
✅ Files skipped from review due to trivial changes (1)
  • docs/operations/Telemetry_Config.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • core/include/gitmind/context.h
  • meson.build
  • migration-progress.md
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use NOLINT to suppress clang-tidy warnings; ALWAYS fix the underlying issue

Files:

  • core/include/gitmind/telemetry/internal/log_format.h
  • core/tests/unit/test_log_formatter.c
  • core/src/app/cache/cache_rebuild_service.c
  • core/src/telemetry/log_format.c
{core,src,apps,tests}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

{core,src,apps,tests}/**/*.{c,h}: Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths
Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required
Equality is OID-first; if both OIDs exist they must match; only fall back to SHA when OIDs are absent
Build refs via gm_build_ref and reject inputs that start with "refs/"
Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes
Formatting via .clang-format (LLVM style, 4 spaces, 80 cols, pointer alignment right); pre-commit runs clang-format
Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with t; header guards start with GITMIND
Includes: prefer specific headers; order/regroup per .clang-format; include-what-you-use
No new clang-tidy warnings; keep touched files tidy-clean
Surface failures via gm_result_t (and variants); ports must not return raw integers
Maintain one responsibility per translation unit where practical; split multi-concern files when touched
Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers
Zero output buffers before formatting/copying on error paths

Files:

  • core/include/gitmind/telemetry/internal/log_format.h
  • core/tests/unit/test_log_formatter.c
  • core/src/app/cache/cache_rebuild_service.c
  • core/src/telemetry/log_format.c
core/include/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public headers under core/include must be umbrella-safe: compile standalone, include only what they use, stable header guards, and provide extern "C" when included from C++

Files:

  • core/include/gitmind/telemetry/internal/log_format.h
core/include/gitmind/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public structs in headers must avoid ABI breaks; append new fields at the struct tail and mark deprecated fields instead of removing

Files:

  • core/include/gitmind/telemetry/internal/log_format.h
core/tests/unit/test_*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests live in core/tests/unit/ and are named test_.c; keep deterministic and isolated

Files:

  • core/tests/unit/test_log_formatter.c
core/tests/**/*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests should use fakes only; integration tests may use real adapters but only inside Docker

Files:

  • core/tests/unit/test_log_formatter.c
core/src/**/{hooks,cache,journal}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid direct libgit2 usage; route repository/ref operations through gm_git_repository_port/gm_git_ref_port adapters

Files:

  • core/src/app/cache/cache_rebuild_service.c
🧠 Learnings (1)
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers

Applied to files:

  • core/src/app/cache/cache_rebuild_service.c
🧬 Code graph analysis (3)
core/include/gitmind/telemetry/internal/log_format.h (1)
core/src/telemetry/log_format.c (1)
  • gm_log_format_render_default (71-107)
core/tests/unit/test_log_formatter.c (1)
core/src/telemetry/log_format.c (1)
  • gm_log_format_render_default (71-107)
core/src/app/cache/cache_rebuild_service.c (4)
core/include/gitmind/ports/logger_port.h (1)
  • gm_logger_log (66-74)
core/src/telemetry/log_format.c (1)
  • gm_log_format_render_default (71-107)
core/include/gitmind/ports/metrics_port.h (3)
  • gm_metrics_timing_ms (72-79)
  • gm_metrics_counter_add (52-59)
  • gm_metrics_gauge_set (62-69)
core/src/error/error.c (1)
  • gm_error_free (161-178)
🔇 Additional comments (4)
core/src/app/cache/cache_rebuild_service.c (2)

161-165: LGTM: Proper error handling for OID prefix extraction.

The refactored call to gm_cache_oid_prefix correctly checks the return value and propagates errors. This aligns with the extracted helper approach.


334-335: LGTM: Safe signature extension for commit OID capture.

The optional out_commit_oid parameter enables telemetry integration without breaking existing callers. The NULL check before assignment is correct.

Also applies to: 372-379

core/src/telemetry/log_format.c (1)

13-69: LGTM: Helper functions implement thorough bounds checking.

The helper functions (append_text, append_json_escaped, append_json_kv) correctly use gm_snprintf and perform defensive bounds checking before each write operation. The JSON escaping properly handles quotes, backslashes, and control characters via \uXXXX encoding. The control flow is clear and the error handling is consistent.

core/include/gitmind/telemetry/internal/log_format.h (1)

1-43: log_format.h is umbrella-safe. It includes <stdbool.h>, <stddef.h>, and result.h (which defines gm_result_void_t), provides proper include guards and extern "C", and compiles standalone.

Comment thread core/src/app/cache/cache_rebuild_service.c Outdated
Comment thread core/src/telemetry/log_format.c
flyingrobots and others added 3 commits October 8, 2025 02:03
… test (build-only) and header compile; keep tests green by not running journal_port in suite; CI green

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e36b172 and 48de1e6.

📒 Files selected for processing (4)
  • core/include/gitmind/ports/journal_command_port.h (1 hunks)
  • core/src/ports/journal/journal_command_port.c (1 hunks)
  • core/tests/unit/test_journal_port.c (1 hunks)
  • meson.build (6 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use NOLINT to suppress clang-tidy warnings; ALWAYS fix the underlying issue

Files:

  • core/src/ports/journal/journal_command_port.c
  • core/tests/unit/test_journal_port.c
  • core/include/gitmind/ports/journal_command_port.h
{core,src,apps,tests}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

{core,src,apps,tests}/**/*.{c,h}: Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths
Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required
Equality is OID-first; if both OIDs exist they must match; only fall back to SHA when OIDs are absent
Build refs via gm_build_ref and reject inputs that start with "refs/"
Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes
Formatting via .clang-format (LLVM style, 4 spaces, 80 cols, pointer alignment right); pre-commit runs clang-format
Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with t; header guards start with GITMIND
Includes: prefer specific headers; order/regroup per .clang-format; include-what-you-use
No new clang-tidy warnings; keep touched files tidy-clean
Surface failures via gm_result_t (and variants); ports must not return raw integers
Maintain one responsibility per translation unit where practical; split multi-concern files when touched
Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers
Zero output buffers before formatting/copying on error paths

Files:

  • core/src/ports/journal/journal_command_port.c
  • core/tests/unit/test_journal_port.c
  • core/include/gitmind/ports/journal_command_port.h
core/src/ports/**

📄 CodeRabbit inference engine (AGENTS.md)

Default implementations for simple inbound coordinators that remain in C may live under core/src/ports/**

Files:

  • core/src/ports/journal/journal_command_port.c
core/src/**/{hooks,cache,journal}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid direct libgit2 usage; route repository/ref operations through gm_git_repository_port/gm_git_ref_port adapters

Files:

  • core/src/ports/journal/journal_command_port.c
core/tests/unit/test_*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests live in core/tests/unit/ and are named test_.c; keep deterministic and isolated

Files:

  • core/tests/unit/test_journal_port.c
core/tests/**/*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests should use fakes only; integration tests may use real adapters but only inside Docker

Files:

  • core/tests/unit/test_journal_port.c
core/include/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public headers under core/include must be umbrella-safe: compile standalone, include only what they use, stable header guards, and provide extern "C" when included from C++

Files:

  • core/include/gitmind/ports/journal_command_port.h
core/include/gitmind/ports/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

Files:

  • core/include/gitmind/ports/journal_command_port.h
core/include/gitmind/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public structs in headers must avoid ABI breaks; append new fields at the struct tail and mark deprecated fields instead of removing

Files:

  • core/include/gitmind/ports/journal_command_port.h
meson.build

📄 CodeRabbit inference engine (AGENTS.md)

Target C23 via Meson c2x and keep warnings-as-errors; register new unit test targets in meson.build

Files:

  • meson.build
🧠 Learnings (3)
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to core/include/gitmind/ports/**/*.h : Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

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: Applies to include/gitmind/**/*.h : Public, namespaced headers live under include/gitmind/

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: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h

Applied to files:

  • meson.build
🧬 Code graph analysis (3)
core/src/ports/journal/journal_command_port.c (1)
core/src/journal/writer.c (2)
  • gm_journal_append (352-356)
  • gm_journal_append_attributed (359-365)
core/tests/unit/test_journal_port.c (2)
core/tests/fakes/git/fake_git_repository_port.c (3)
  • gm_fake_git_repository_port_init (195-229)
  • gm_fake_git_repository_port_last_update_ref (482-485)
  • gm_fake_git_repository_port_dispose (231-237)
core/src/ports/journal/journal_command_port.c (2)
  • gm_cmd_journal_port_init (50-65)
  • gm_cmd_journal_port_dispose (67-72)
core/include/gitmind/ports/journal_command_port.h (1)
core/src/ports/journal/journal_command_port.c (2)
  • gm_cmd_journal_port_init (50-65)
  • gm_cmd_journal_port_dispose (67-72)
🔇 Additional comments (9)
core/tests/unit/test_journal_port.c (1)

1-68: LGTM! Test structure and logic are sound.

The test correctly exercises the journal command port's append operation by:

  • Wiring a fake Git repository port to capture ref updates
  • Creating a minimal valid edge with OIDs
  • Invoking the port's append method
  • Verifying the expected ref update at refs/gitmind/edges/main
  • Properly cleaning up the test environment variable

Note: The heap allocation at line 24 is intentional—putenv takes ownership of the string, so it should not be freed.

core/src/ports/journal/journal_command_port.c (3)

16-28: LGTM! Proper validation and delegation.

The append_impl function correctly validates inputs, delegates to the existing gm_journal_append API, and translates the return code into a gm_result_void_t with appropriate error context.


30-43: LGTM! Consistent with append implementation.

The append_attr_impl function mirrors the structure and validation of append_impl, correctly delegating to gm_journal_append_attributed.


50-72: LGTM! Lifecycle functions are properly implemented.

The initialization and disposal functions follow best practices:

  • Thorough input validation
  • Proper error handling for allocation failures
  • Clean state initialization via calloc
  • Defensive NULL checks in dispose
  • Proper pointer nullification during cleanup
core/include/gitmind/ports/journal_command_port.h (2)

1-38: LGTM! Header follows port design pattern correctly.

The header is well-structured and umbrella-safe:

  • Proper SPDX license and header guard with GITMIND_ prefix
  • Complete dependency includes for standalone compilation
  • POD struct with non-owning vtable pointer and opaque state
  • Vtable with function pointers only (no inline behavior)
  • extern "C" guard for C++ compatibility

As per coding guidelines for core/include/gitmind/ports/**/*.h.


40-43: LGTM! Lifecycle functions properly declared.

The init function correctly uses GM_NODISCARD to ensure callers check the result, and both function signatures align with their implementations in core/src/ports/journal/journal_command_port.c.

meson.build (3)

124-126: LGTM! New source files properly integrated.

The new source files for telemetry, OID prefix support, port implementations, and adapters are correctly added to the build. This aligns with the PR's hexagonal architecture migration goals.

Also applies to: 132-134, 142-143


341-345: LGTM! Test executables properly defined.

All new test executables are correctly configured with:

  • Appropriate source files and fake ports
  • Required dependencies (libsodium, libgit2, threads)
  • Correct include directories

Also applies to: 364-368, 387-394, 396-400, 402-406, 408-413


471-475: LGTM! New port headers added to compilation checks.

The new port headers are correctly added to the public_headers list, ensuring they compile standalone and are umbrella-safe. This follows the established pattern for public API headers.

Comment thread meson.build
flyingrobots and others added 3 commits October 8, 2025 02:11

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
core/tests/unit/test_cache_telemetry_emit.c (2)

110-118: Replace snprintf/memcpy with gm_snprintf/gm_strcpy_safe and handle truncation.

The helper bypasses the mandated safe wrappers, so truncation or format errors would go unnoticed. Please switch to gm_snprintf, copy via gm_strcpy_safe, and assert on their return values before calling putenv.

 static void set_env(const char *k, const char *v) {
     char buf[256];
     if (v == NULL) v = "";
-    int n = snprintf(buf, sizeof(buf), "%s=%s", k, v);
-    assert(n > 0 && (size_t)n < sizeof(buf));
+    int n = gm_snprintf(buf, sizeof(buf), "%s=%s", k, v);
+    assert(n >= 0 && (size_t)n < sizeof(buf));
     char *heap = (char *)malloc((size_t)n + 1);
     assert(heap != NULL);
-    memcpy(heap, buf, (size_t)n + 1);
+    if (gm_strcpy_safe(heap, (size_t)n + 1, buf) != 0) {
+        heap[0] = '\0';
+        free(heap);
+        assert(!"set_env: gm_strcpy_safe truncated");
+    }
     assert(putenv(heap) == 0);
 }

133-138: Check gm_strcpy_safe result before using sr.gitdir.

We drop the return code, so a truncation would silently leave sr.gitdir invalid. Capture the result and assert success (or handle the failure) before proceeding.

-    gm_strcpy_safe(sr.gitdir, sizeof(sr.gitdir), "/fake/state");
+    int copy_rc = gm_strcpy_safe(sr.gitdir, sizeof(sr.gitdir), "/fake/state");
+    assert(copy_rc == 0);
🧹 Nitpick comments (3)
core/tests/unit/test_journal_port.c (1)

43-51: LGTM!

The verification and cleanup are properly implemented:

  • Correctly retrieves and verifies the ref update from the fake port.
  • Proper resource disposal prevents leaks.
  • The substring check using strstr is acceptable for testing.

For slightly more precise verification, you could use exact string comparison:

-    assert(strstr(last_ref, "refs/gitmind/edges/main") != NULL);
+    assert(strcmp(last_ref, "refs/gitmind/edges/main") == 0);

However, the current approach is more flexible if the exact format evolves.

core/src/journal/reader.c (2)

36-36: Remove duplicate include of constants_internal.h

This header is already included at Line 10. Drop the duplicate to keep includes tidy and avoid IWYU noise.

-#include "gitmind/constants_internal.h" /* MILLIS_PER_SECOND */

415-419: Use monotonic wall-clock for duration; guard clock() failures

clock() measures CPU time, not wall time, and may return (clock_t)-1. Prefer a monotonic timer; at minimum, guard failures to avoid bogus large durations.

-    clock_t st = clock();
+    clock_t st = clock();
     int rc_walk = walk_journal_generic(&rctx, ref_name);
-
-    uint64_t dur_ms = (uint64_t)((clock() - st) / CLOCKS_PER_MS);
+    uint64_t dur_ms = 0;
+    clock_t en = clock();
+    if (st != (clock_t)-1 && en != (clock_t)-1 && en >= st) {
+        dur_ms = (uint64_t)((en - st) / CLOCKS_PER_MS);
+    }

Optional (preferred): switch to a monotonic timer (e.g., clock_gettime(CLOCK_MONOTONIC) or timespec_get) to avoid CPU-time semantics; I can provide a small helper if desired.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 48de1e6 and 5dad40c.

📒 Files selected for processing (4)
  • core/src/journal/reader.c (3 hunks)
  • core/src/journal/writer.c (5 hunks)
  • core/tests/unit/test_cache_telemetry_emit.c (1 hunks)
  • core/tests/unit/test_journal_port.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • core/src/journal/writer.c
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use NOLINT to suppress clang-tidy warnings; ALWAYS fix the underlying issue

Files:

  • core/tests/unit/test_journal_port.c
  • core/src/journal/reader.c
  • core/tests/unit/test_cache_telemetry_emit.c
{core,src,apps,tests}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

{core,src,apps,tests}/**/*.{c,h}: Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths
Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required
Equality is OID-first; if both OIDs exist they must match; only fall back to SHA when OIDs are absent
Build refs via gm_build_ref and reject inputs that start with "refs/"
Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes
Formatting via .clang-format (LLVM style, 4 spaces, 80 cols, pointer alignment right); pre-commit runs clang-format
Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with t; header guards start with GITMIND
Includes: prefer specific headers; order/regroup per .clang-format; include-what-you-use
No new clang-tidy warnings; keep touched files tidy-clean
Surface failures via gm_result_t (and variants); ports must not return raw integers
Maintain one responsibility per translation unit where practical; split multi-concern files when touched
Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers
Zero output buffers before formatting/copying on error paths

Files:

  • core/tests/unit/test_journal_port.c
  • core/src/journal/reader.c
  • core/tests/unit/test_cache_telemetry_emit.c
core/tests/unit/test_*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests live in core/tests/unit/ and are named test_.c; keep deterministic and isolated

Files:

  • core/tests/unit/test_journal_port.c
  • core/tests/unit/test_cache_telemetry_emit.c
core/tests/**/*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests should use fakes only; integration tests may use real adapters but only inside Docker

Files:

  • core/tests/unit/test_journal_port.c
  • core/tests/unit/test_cache_telemetry_emit.c
core/src/**/{hooks,cache,journal}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid direct libgit2 usage; route repository/ref operations through gm_git_repository_port/gm_git_ref_port adapters

Files:

  • core/src/journal/reader.c
🧠 Learnings (1)
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths

Applied to files:

  • core/tests/unit/test_cache_telemetry_emit.c
🧬 Code graph analysis (3)
core/tests/unit/test_journal_port.c (2)
core/tests/fakes/git/fake_git_repository_port.c (4)
  • gm_fake_git_repository_port_init (195-229)
  • gm_fake_git_repository_port_set_head_branch (247-261)
  • gm_fake_git_repository_port_last_update_ref (482-485)
  • gm_fake_git_repository_port_dispose (231-237)
core/src/ports/journal/journal_command_port.c (2)
  • gm_cmd_journal_port_init (50-65)
  • gm_cmd_journal_port_dispose (67-72)
core/src/journal/reader.c (3)
core/src/telemetry/log_format.c (1)
  • gm_log_format_render_default (71-107)
core/include/gitmind/ports/logger_port.h (1)
  • gm_logger_log (66-74)
core/include/gitmind/ports/metrics_port.h (1)
  • gm_metrics_timing_ms (72-79)
core/tests/unit/test_cache_telemetry_emit.c (7)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/include/gitmind/security/memory.h (1)
  • gm_memset_safe (47-59)
core/tests/unit/test_telemetry_cfg.c (1)
  • set_env (14-24)
core/tests/fakes/logging/fake_logger_port.c (2)
  • gm_fake_logger_port_init (31-46)
  • gm_fake_logger_port_dispose (48-53)
core/tests/fakes/metrics/fake_metrics_port.c (2)
  • gm_fake_metrics_port_init (60-73)
  • gm_fake_metrics_port_dispose (75-80)
core/src/app/cache/cache_rebuild_service.c (1)
  • gm_cache_rebuild_execute (476-643)
core/tests/fakes/fs/fake_fs_temp_port.c (1)
  • gm_fake_fs_temp_port_dispose (252-259)
🔇 Additional comments (2)
core/tests/unit/test_journal_port.c (2)

1-13: LGTM!

The includes are appropriate and properly organized. SPDX header and copyright are correctly placed.


17-41: LGTM!

The test setup and execution are well-structured:

  • Properly uses the fake repository port as required for unit tests.
  • Context and port initialization follow the expected patterns.
  • Minimal edge initialization is sufficient for testing the append path.
  • Assertions provide clear failure points.

Comment thread core/src/journal/reader.c Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
core/src/journal/reader.c (1)

10-11: Remove duplicate include

gitmind/constants_internal.h is included twice.

-#include "gitmind/constants_internal.h"
@@
-#include "gitmind/constants_internal.h" /* MILLIS_PER_SECOND */
+#include "gitmind/constants_internal.h" /* MILLIS_PER_SECOND */

Also applies to: 39-41

♻️ Duplicate comments (6)
core/src/app/cache/cache_rebuild_service.c (2)

513-538: Honor gm_telemetry_ return values to avoid leaked errors*

The returns from gm_telemetry_cfg_load and gm_telemetry_build_tags are still ignored. When either fails, the embedded gm_error_t leaks and we continue with undefined telemetry state. Capture each result, free any error payload, and decide whether to proceed with defaults or abort.

-    gm_telemetry_cfg_t tcfg = {0};
-    (void)gm_telemetry_cfg_load(&tcfg, gm_env_port_system());
+    gm_telemetry_cfg_t tcfg = {0};
+    gm_result_void_t cfg_rc = gm_telemetry_cfg_load(&tcfg, gm_env_port_system());
+    if (!cfg_rc.ok) {
+        if (cfg_rc.u.err != NULL) {
+            gm_error_free(cfg_rc.u.err);
+        }
+        gm_memset_safe(&tcfg, sizeof(tcfg), 0, sizeof(tcfg));
+    }
@@
-    (void)gm_telemetry_build_tags(&tcfg, branch, mode, repo_canon, &repo_id,
-                                  tags, sizeof(tags));
+    gm_result_void_t tags_rc =
+        gm_telemetry_build_tags(&tcfg, branch, mode, repo_canon, &repo_id,
+                                tags, sizeof(tags));
+    if (!tags_rc.ok) {
+        if (tags_rc.u.err != NULL) {
+            gm_error_free(tags_rc.u.err);
+        }
+        tags[0] = '\0';
+    }

As per coding guidelines


633-672: Check gm_snprintf results per project guidelines

gm_snprintf calls still discard their return values. The guidelines require detecting truncation/failure and treating it as an error (and freeing any cascading errors). Please capture each return, verify it is within bounds, and handle failure before logging or emitting diagnostics.

-        (void)gm_snprintf(edge_count_buf, sizeof(edge_count_buf), "%u",
-                          (unsigned)meta.edge_count);
+        int edge_fmt = gm_snprintf(edge_count_buf, sizeof(edge_count_buf), "%u",
+                                   (unsigned)meta.edge_count);
+        if (edge_fmt < 0 || (size_t)edge_fmt >= sizeof(edge_count_buf)) {
+            return GM_ERR_BUFFER_TOO_SMALL;
+        }

Replicate this pattern for dur_buf and the failure code_buf.

As per coding guidelines

core/src/journal/reader.c (1)

298-353: Handle gm_result_void_t; free repo_canon; init/validate buffers (same as earlier review)

Return values from gm_* calls are ignored and repo_canon is leaked; msg/dur_buf need init and gm_snprintf rc checks. Please apply the previously suggested fixes (capture/handle gm_result_void_t, free repo_canon after gm_telemetry_build_tags, zero/validate buffers) to this block.

See earlier review for concrete diff.

core/tests/unit/test_cache_telemetry_emit.c (2)

110-119: Use gm_snprintf/gm_strcpy_safe in set_env (already flagged)

Replace snprintf/memcpy with gm_snprintf + gm_strcpy_safe and check rc; bail on truncation. Also include gitmind/security/string.h if not present.

As per coding guidelines


133-138: Check gm_strcpy_safe result when setting sr.gitdir (already flagged)

Capture and assert rc to avoid silent truncation.

As per coding guidelines

meson.build (1)

440-445: Missing test registration for test_journal_port.

The test_journal_port executable is defined but not registered in the test registration section (lines 485-501). This means the test won't run as part of the Meson test suite.

Add the missing test registration:

 test('cache_oid_prefix', test_cache_oid_prefix)
+test('journal_port', test_journal_port)
🧹 Nitpick comments (17)
core/tests/unit/test_cache_branch_limits.c (1)

53-53: Consider migrating to gm_snprintf with return checking.

The existing code uses snprintf without checking the return value. The coding guidelines require gm_snprintf with return checking for all string operations.

Apply this diff to align with coding guidelines (similar pattern used in test_cache_query.c:40-41):

-    snprintf(refname, sizeof refname, "refs/heads/%s", branch);
+    int wn = gm_snprintf(refname, sizeof refname, "refs/heads/%s", branch);
+    assert(wn >= 0 && (size_t)wn < sizeof refname);
core/tests/fakes/git/fake_git_repository_port.c (1)

787-803: Check return value from gm_strcpy_safe on Line 797-799.

The call to gm_strcpy_safe on Lines 797-799 explicitly discards the return value with (void), which means truncation errors are silently ignored. While this might be acceptable for test code, it could hide issues if commit messages unexpectedly exceed the buffer. Consider whether truncation should be detected and flagged, or document why silent truncation is acceptable here.

For better test diagnostics, consider checking the return value:

                     commit->has_message = (fake->last_commit_message[0] != '\0');
                     if (commit->has_message) {
-                        (void)gm_strcpy_safe(commit->message,
-                                             sizeof(commit->message),
-                                             fake->last_commit_message);
+                        int rc = gm_strcpy_safe(commit->message,
+                                                sizeof(commit->message),
+                                                fake->last_commit_message);
+                        if (rc != 0) {
+                            /* Truncated; reset has_message to avoid misleading data */
+                            commit->has_message = false;
+                            commit->message[0] = '\0';
+                        }
                     }
core/src/adapters/diagnostics/stderr_diagnostics_adapter.c (2)

16-34: Consider flushing stderr after diagnostic emission.

The emit_impl function writes diagnostic output to stderr without flushing. If stderr is line-buffered or block-buffered in some environments, diagnostic messages may not appear immediately. Consider adding fflush(stderr) after Line 32 to ensure timely visibility of diagnostics.

Apply this diff to flush stderr:

     }
     fputc('\n', stderr);
+    fflush(stderr);
     return gm_ok_void();
 }

12-14: Unused field 'enabled' in state struct.

The enabled field in gm_stderr_diag_state_t is marked as unused but allocated and never referenced. If this is a placeholder for future functionality, consider adding a comment explaining the intent or removing it until needed.

If the field is truly unused, consider removing it:

 typedef struct {
-    int enabled; /* future toggle; unused for now */
+    /* Future: add toggle field when needed */
 } gm_stderr_diag_state_t;
core/src/domain/journal/append_planner.c (1)

20-23: Document lifetime requirements for out_plan pointers.

Lines 20-23 assign pointers (tree_oid, message, parents) directly into out_plan without copying. This means the caller must ensure these inputs remain valid for the lifetime of out_plan. Consider adding a brief doc comment in the header (gitmind/journal/internal/append_plan.h) clarifying that the plan does not own the pointed-to data.

Example header comment:

/**
 * Build a journal commit plan.
 * 
 * @param empty_tree_oid Tree OID (must remain valid for plan's lifetime)
 * @param parent_oid_opt Optional parent OID (must remain valid if non-NULL)
 * @param message Commit message (must remain valid for plan's lifetime)
 * @param out_plan Output plan (does not own pointed-to data)
 * @return gm_result_void_t
 */
core/tests/unit/test_journal_nff_retry.c (1)

84-92: Simplify or clarify test comment.

Lines 84-92 contain a lengthy comment explaining the head resolution bypass. While the intent is clear, the comment is somewhat verbose and fragmented. Consider condensing it or moving the explanation to a function-level docstring for better readability.

Example condensed comment:

-    /* The writer resolves head branch through repo port; our stub lacks it,
-       so we call the internal append via current-branch path by bypassing head.
-       To keep the test minimal, set branch name inline by initializing the
-       ref in the writer (we can't). Instead, rely on the fact that when head
-       lookup fails, writer returns error; so we simulate head by injecting a
-       pre-known branch via overriding resolve function is not possible. We
-       avoid head resolution by calling gm_journal_create_commit with an
-       explicit ref and spec assembly paths exercised by flush/updates.
-    */
+    /* Writer uses head_branch from stub repo; on NFF, retry logic kicks in */
core/tests/fakes/diagnostics/fake_diagnostics_port.h (1)

15-20: Document or enforce limits on diagnostic event count.

The gm_fake_diag_state_t struct uses fixed-size arrays (meta[64], kvs[64][8], etc.). If a test emits more than 64 diagnostic events, silent overflow occurs. Consider documenting this limit clearly or adding runtime checks in the implementation to prevent silent data loss during tests.

Add a comment documenting the limit:

 typedef struct {
+    /* Capacity: up to 64 diagnostic events, 8 KVs per event */
     struct { char component[32]; char event[64]; } meta[64];
     struct { char key[32]; char value[64]; } kvs[64][8];
     size_t kv_counts[64];
     size_t count;
 } gm_fake_diag_state_t;
core/tests/unit/test_journal_port_append_flow.c (1)

52-67: Consider helper function for edge construction.

Lines 52-67 manually construct two edges with similar patterns. Consider extracting a helper function to reduce duplication and improve maintainability, especially if more tests need edge construction.

Example helper:

static void make_test_edge(gm_edge_t *edge, const uint8_t *src_raw, 
                          const uint8_t *tgt_raw, gm_rel_type_t rel,
                          const char *src_path, const char *tgt_path) {
    assert(gm_oid_from_raw(&edge->src_oid, src_raw, GM_OID_RAWSZ) == GM_OK);
    assert(gm_oid_from_raw(&edge->tgt_oid, tgt_raw, GM_OID_RAWSZ) == GM_OK);
    edge->rel_type = rel;
    edge->confidence = 0x3C00;
    assert(gm_strcpy_safe(edge->src_path, sizeof edge->src_path, src_path) == 0);
    assert(gm_strcpy_safe(edge->tgt_path, sizeof edge->tgt_path, tgt_path) == 0);
    assert(gm_ulid_generate(edge->ulid).ok);
}

Then use:

make_test_edge(&edges[0], A, B, GM_REL_IMPLEMENTS, "A", "B");
make_test_edge(&edges[1], A, C, GM_REL_DEPENDS_ON, "A", "C");
core/src/domain/journal/codec.c (2)

29-31: Redundant check before null-terminating encoded string.

Line 29 checks if (required > 0U) before null-terminating at required - 1U, but required is guaranteed to be > 0 because sodium_base64_ENCODED_LEN always includes space for the null terminator. The check is redundant and can be removed for clarity.

     sodium_bin2base64(encoded, required, cbor_data, cbor_len, variant);
-    if (required > 0U) {
-        encoded[required - 1U] = '\0';
-    }
+    encoded[required - 1U] = '\0';
     *message_out = encoded;

42-44: Document caller responsibility for decoded buffer size.

Line 42 validates that decoded and decoded_length are non-NULL, but does not verify that *decoded_length is large enough to hold the decoded output. sodium_base642bin will fail if the buffer is too small, but the error message "decode requires buffers" is generic. Consider documenting in the header that the caller must pass a sufficiently sized buffer and that *decoded_length must be pre-initialized to the buffer capacity.

Add a header comment in core/include/gitmind/journal/internal/codec.h:

/**
 * Decode a base64 commit message into binary CBOR.
 * 
 * @param raw_message Base64-encoded string
 * @param decoded Output buffer (caller must allocate sufficient space)
 * @param decoded_length [in/out] Buffer capacity on input; decoded size on output
 * @return gm_result_void_t (GM_ERR_INVALID_FORMAT if base64 is invalid)
 */
core/include/gitmind/journal/internal/codec.h (2)

16-20: Add documentation for memory ownership and lifetime.

Lines 16-20 declare gm_journal_encode_message but do not document that *message_out is heap-allocated and must be freed by the caller. Consider adding a brief doc comment clarifying memory ownership and lifetime expectations.

-/* Encode a CBOR payload into a base64 message string for commit bodies. */
+/**
+ * Encode a CBOR payload into a base64 message string for commit bodies.
+ * 
+ * @param cbor_data Input CBOR bytes
+ * @param cbor_len Size of CBOR payload
+ * @param message_out [out] Heap-allocated base64 string (caller must free)
+ * @param message_len_out [out, optional] Length of allocated string (including null terminator)
+ * @return gm_result_void_t
+ */
 GM_NODISCARD gm_result_void_t gm_journal_encode_message(const uint8_t *cbor_data,

22-25: Add documentation for buffer requirements.

Lines 22-25 declare gm_journal_decode_message without documenting that decoded must be a pre-allocated buffer of sufficient size and that decoded_length is an in/out parameter. Add a doc comment clarifying these requirements.

-/* Decode a commit message (base64) into binary CBOR bytes. */
+/**
+ * Decode a base64 commit message into binary CBOR bytes.
+ * 
+ * @param raw_message Base64-encoded commit message
+ * @param decoded [out] Pre-allocated buffer for decoded CBOR
+ * @param decoded_length [in/out] Buffer capacity on input; decoded size on output
+ * @return gm_result_void_t (GM_ERR_INVALID_FORMAT if base64 is malformed)
+ */
 GM_NODISCARD gm_result_void_t gm_journal_decode_message(const char *raw_message,
core/include/gitmind/journal/internal/read_decoder.h (1)

19-25: Doc nit: return wording

Change "Returns GM_OK" to "returns gm_ok_void (gm_result_void_t.ok==true)" to match API semantics.

core/src/journal/reader.c (3)

325-333: Prefer monotonic wall-clock for duration

clock() is CPU time and may misrepresent I/O-bound durations. Use a monotonic wall clock (e.g., gm_time_monotonic_ms if available) for metrics.


69-72: Check gm_snprintf in debug logger

Validate gm_snprintf return and null-terminate/zero on failure to honor guidelines.

As per coding guidelines


200-216: Emit diagnostics ok, but also surface code safely

Consider initializing cbuf to empty and checking gm_snprintf return before use. Optional.

core/tests/unit/test_journal_e2e_libgit2.c (1)

1-15: Classify as integration test

This uses real libgit2 and filesystem. Consider moving to an integration tests directory or gating under Docker-only to align with test policy.

📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5dad40c and 45cb56f.

📒 Files selected for processing (38)
  • .gitignore (1 hunks)
  • AGENTS.md (5 hunks)
  • README.md (2 hunks)
  • apps/cli/README.md (1 hunks)
  • apps/cli/Scripting_Patterns.md (1 hunks)
  • apps/cli/link.md (1 hunks)
  • apps/cli/list.md (1 hunks)
  • apps/cli/main.c (4 hunks)
  • apps/cli/main.md (2 hunks)
  • core/include/gitmind/context.h (2 hunks)
  • core/include/gitmind/journal/internal/append_plan.h (1 hunks)
  • core/include/gitmind/journal/internal/codec.h (1 hunks)
  • core/include/gitmind/journal/internal/read_decoder.h (1 hunks)
  • core/include/gitmind/ports/diagnostic_port.h (1 hunks)
  • core/src/adapters/diagnostics/stderr_diagnostics_adapter.c (1 hunks)
  • core/src/adapters/diagnostics/stderr_diagnostics_adapter.h (1 hunks)
  • core/src/app/cache/cache_rebuild_service.c (10 hunks)
  • core/src/domain/journal/append_planner.c (1 hunks)
  • core/src/domain/journal/codec.c (1 hunks)
  • core/src/domain/journal/read_decoder.c (1 hunks)
  • core/src/journal/reader.c (9 hunks)
  • core/src/journal/writer.c (11 hunks)
  • core/tests/fakes/diagnostics/fake_diagnostics_port.c (1 hunks)
  • core/tests/fakes/diagnostics/fake_diagnostics_port.h (1 hunks)
  • core/tests/fakes/git/fake_git_repository_port.c (1 hunks)
  • core/tests/unit/test_cache_branch_limits.c (1 hunks)
  • core/tests/unit/test_cache_query.c (1 hunks)
  • core/tests/unit/test_cache_telemetry_emit.c (1 hunks)
  • core/tests/unit/test_cli_json_env.c (1 hunks)
  • core/tests/unit/test_diagnostics_port.c (1 hunks)
  • core/tests/unit/test_journal_e2e_libgit2.c (1 hunks)
  • core/tests/unit/test_journal_nff_retry.c (1 hunks)
  • core/tests/unit/test_journal_port_append_flow.c (1 hunks)
  • docs/architecture/hexagonal/Journal.md (1 hunks)
  • docs/operations/Diagnostics_Events.md (1 hunks)
  • docs/operations/Observability.md (1 hunks)
  • docs/operations/Telemetry_Config.md (1 hunks)
  • meson.build (6 hunks)
✅ Files skipped from review due to trivial changes (8)
  • docs/operations/Observability.md
  • .gitignore
  • apps/cli/link.md
  • apps/cli/Scripting_Patterns.md
  • apps/cli/README.md
  • apps/cli/list.md
  • docs/architecture/hexagonal/Journal.md
  • docs/operations/Diagnostics_Events.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • docs/operations/Telemetry_Config.md
  • core/include/gitmind/context.h
  • AGENTS.md
🧰 Additional context used
📓 Path-based instructions (14)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use NOLINT to suppress clang-tidy warnings; ALWAYS fix the underlying issue

Files:

  • core/src/adapters/diagnostics/stderr_diagnostics_adapter.h
  • core/tests/unit/test_diagnostics_port.c
  • core/tests/unit/test_journal_e2e_libgit2.c
  • core/src/adapters/diagnostics/stderr_diagnostics_adapter.c
  • core/src/domain/journal/append_planner.c
  • core/include/gitmind/journal/internal/codec.h
  • core/src/domain/journal/read_decoder.c
  • core/tests/unit/test_cli_json_env.c
  • core/tests/unit/test_journal_port_append_flow.c
  • core/include/gitmind/journal/internal/read_decoder.h
  • core/src/domain/journal/codec.c
  • core/tests/unit/test_cache_query.c
  • core/tests/unit/test_cache_telemetry_emit.c
  • core/tests/fakes/diagnostics/fake_diagnostics_port.h
  • core/src/journal/writer.c
  • apps/cli/main.c
  • core/include/gitmind/journal/internal/append_plan.h
  • core/tests/fakes/diagnostics/fake_diagnostics_port.c
  • core/src/journal/reader.c
  • core/tests/fakes/git/fake_git_repository_port.c
  • core/include/gitmind/ports/diagnostic_port.h
  • core/tests/unit/test_journal_nff_retry.c
  • core/tests/unit/test_cache_branch_limits.c
  • core/src/app/cache/cache_rebuild_service.c
{core,src,apps,tests}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

{core,src,apps,tests}/**/*.{c,h}: Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths
Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required
Equality is OID-first; if both OIDs exist they must match; only fall back to SHA when OIDs are absent
Build refs via gm_build_ref and reject inputs that start with "refs/"
Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes
Formatting via .clang-format (LLVM style, 4 spaces, 80 cols, pointer alignment right); pre-commit runs clang-format
Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with t; header guards start with GITMIND
Includes: prefer specific headers; order/regroup per .clang-format; include-what-you-use
No new clang-tidy warnings; keep touched files tidy-clean
Surface failures via gm_result_t (and variants); ports must not return raw integers
Maintain one responsibility per translation unit where practical; split multi-concern files when touched
Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers
Zero output buffers before formatting/copying on error paths

Files:

  • core/src/adapters/diagnostics/stderr_diagnostics_adapter.h
  • core/tests/unit/test_diagnostics_port.c
  • core/tests/unit/test_journal_e2e_libgit2.c
  • core/src/adapters/diagnostics/stderr_diagnostics_adapter.c
  • core/src/domain/journal/append_planner.c
  • core/include/gitmind/journal/internal/codec.h
  • core/src/domain/journal/read_decoder.c
  • core/tests/unit/test_cli_json_env.c
  • core/tests/unit/test_journal_port_append_flow.c
  • core/include/gitmind/journal/internal/read_decoder.h
  • core/src/domain/journal/codec.c
  • core/tests/unit/test_cache_query.c
  • core/tests/unit/test_cache_telemetry_emit.c
  • core/tests/fakes/diagnostics/fake_diagnostics_port.h
  • core/src/journal/writer.c
  • apps/cli/main.c
  • core/include/gitmind/journal/internal/append_plan.h
  • core/tests/fakes/diagnostics/fake_diagnostics_port.c
  • core/src/journal/reader.c
  • core/tests/fakes/git/fake_git_repository_port.c
  • core/include/gitmind/ports/diagnostic_port.h
  • core/tests/unit/test_journal_nff_retry.c
  • core/tests/unit/test_cache_branch_limits.c
  • core/src/app/cache/cache_rebuild_service.c
core/src/adapters/**/*_adapter.h

📄 CodeRabbit inference engine (AGENTS.md)

Adapter private headers colocate under core/src/adapters//_adapter.h

Files:

  • core/src/adapters/diagnostics/stderr_diagnostics_adapter.h
core/tests/unit/test_*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests live in core/tests/unit/ and are named test_.c; keep deterministic and isolated

Files:

  • core/tests/unit/test_diagnostics_port.c
  • core/tests/unit/test_journal_e2e_libgit2.c
  • core/tests/unit/test_cli_json_env.c
  • core/tests/unit/test_journal_port_append_flow.c
  • core/tests/unit/test_cache_query.c
  • core/tests/unit/test_cache_telemetry_emit.c
  • core/tests/unit/test_journal_nff_retry.c
  • core/tests/unit/test_cache_branch_limits.c
core/tests/**/*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests should use fakes only; integration tests may use real adapters but only inside Docker

Files:

  • core/tests/unit/test_diagnostics_port.c
  • core/tests/unit/test_journal_e2e_libgit2.c
  • core/tests/unit/test_cli_json_env.c
  • core/tests/unit/test_journal_port_append_flow.c
  • core/tests/unit/test_cache_query.c
  • core/tests/unit/test_cache_telemetry_emit.c
  • core/tests/fakes/diagnostics/fake_diagnostics_port.c
  • core/tests/fakes/git/fake_git_repository_port.c
  • core/tests/unit/test_journal_nff_retry.c
  • core/tests/unit/test_cache_branch_limits.c
core/src/adapters/**/*_adapter.c

📄 CodeRabbit inference engine (AGENTS.md)

Runtime adapters live under core/src/adapters//_adapter.c and expose factories returning the port vtable plus state with teardown hooks

Files:

  • core/src/adapters/diagnostics/stderr_diagnostics_adapter.c
core/src/domain/**

📄 CodeRabbit inference engine (AGENTS.md)

Domain core code under core/src/domain/** must be pure/deterministic (no direct IO/libgit2/global state)

Files:

  • core/src/domain/journal/append_planner.c
  • core/src/domain/journal/read_decoder.c
  • core/src/domain/journal/codec.c
core/src/domain/{edge,journal,cache,attribution,hooks}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

Wrap all side effects behind outbound ports; no direct IO or libgit2 in domain modules

Files:

  • core/src/domain/journal/append_planner.c
  • core/src/domain/journal/read_decoder.c
  • core/src/domain/journal/codec.c
core/src/**/{hooks,cache,journal}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid direct libgit2 usage; route repository/ref operations through gm_git_repository_port/gm_git_ref_port adapters

Files:

  • core/src/domain/journal/append_planner.c
  • core/src/domain/journal/read_decoder.c
  • core/src/domain/journal/codec.c
  • core/src/journal/writer.c
  • core/src/journal/reader.c
  • core/src/app/cache/cache_rebuild_service.c
core/include/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public headers under core/include must be umbrella-safe: compile standalone, include only what they use, stable header guards, and provide extern "C" when included from C++

Files:

  • core/include/gitmind/journal/internal/codec.h
  • core/include/gitmind/journal/internal/read_decoder.h
  • core/include/gitmind/journal/internal/append_plan.h
  • core/include/gitmind/ports/diagnostic_port.h
core/include/gitmind/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Public structs in headers must avoid ABI breaks; append new fields at the struct tail and mark deprecated fields instead of removing

Files:

  • core/include/gitmind/journal/internal/codec.h
  • core/include/gitmind/journal/internal/read_decoder.h
  • core/include/gitmind/journal/internal/append_plan.h
  • core/include/gitmind/ports/diagnostic_port.h
core/tests/fakes/**

📄 CodeRabbit inference engine (AGENTS.md)

Provide deterministic fakes/mocks/stubs for every outbound port under core/tests/fakes/** with harnesses verifying contract invariants

Files:

  • core/tests/fakes/diagnostics/fake_diagnostics_port.h
  • core/tests/fakes/diagnostics/fake_diagnostics_port.c
  • core/tests/fakes/git/fake_git_repository_port.c
core/include/gitmind/ports/**/*.h

📄 CodeRabbit inference engine (AGENTS.md)

Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

Files:

  • core/include/gitmind/ports/diagnostic_port.h
meson.build

📄 CodeRabbit inference engine (AGENTS.md)

Target C23 via Meson c2x and keep warnings-as-errors; register new unit test targets in meson.build

Files:

  • meson.build
🧠 Learnings (7)
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths

Applied to files:

  • core/tests/unit/test_cache_telemetry_emit.c
  • core/src/app/cache/cache_rebuild_service.c
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with _t; header guards start with GITMIND_

Applied to files:

  • core/src/journal/writer.c
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to core/src/**/{hooks,cache,journal}/**/*.{c,h} : Avoid direct libgit2 usage; route repository/ref operations through gm_git_repository_port/gm_git_ref_port adapters

Applied to files:

  • apps/cli/main.c
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to core/include/gitmind/ports/**/*.h : Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

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: Applies to include/gitmind/**/*.h : Public, namespaced headers live under include/gitmind/

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: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h

Applied to files:

  • meson.build
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers

Applied to files:

  • core/src/app/cache/cache_rebuild_service.c
🧬 Code graph analysis (14)
core/src/adapters/diagnostics/stderr_diagnostics_adapter.h (1)
core/src/adapters/diagnostics/stderr_diagnostics_adapter.c (1)
  • gm_stderr_diagnostics_port_init (40-52)
core/tests/unit/test_diagnostics_port.c (3)
core/tests/fakes/diagnostics/fake_diagnostics_port.c (2)
  • gm_fake_diag_port_init (38-52)
  • gm_fake_diag_port_dispose (54-59)
core/src/app/cache/cache_rebuild_service.c (1)
  • gm_cache_rebuild_execute (494-676)
core/tests/fakes/fs/fake_fs_temp_port.c (1)
  • gm_fake_fs_temp_port_dispose (252-259)
core/tests/unit/test_journal_e2e_libgit2.c (7)
core/src/adapters/fs/posix_temp_adapter.c (1)
  • gm_posix_fs_temp_port_create (628-653)
core/src/adapters/git/libgit2_repository_port.c (1)
  • gm_libgit2_repository_port_create (1111-1139)
core/tests/fakes/logging/fake_logger_port.c (1)
  • gm_fake_logger_port_init (31-46)
core/tests/fakes/metrics/fake_metrics_port.c (1)
  • gm_fake_metrics_port_init (60-73)
core/src/ports/journal/journal_command_port.c (2)
  • gm_cmd_journal_port_init (50-65)
  • gm_cmd_journal_port_dispose (67-72)
core/src/edge/edge.c (1)
  • gm_edge_create (56-107)
core/src/journal/reader.c (1)
  • gm_journal_read (357-361)
core/src/domain/journal/read_decoder.c (4)
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/edge/attributed.c (1)
  • gm_edge_attributed_decode_cbor_ex (290-294)
core/src/edge/edge.c (1)
  • gm_edge_decode_cbor_ex (515-517)
core/tests/unit/test_journal_port_append_flow.c (9)
core/tests/fakes/git/fake_git_repository_port.c (5)
  • gm_fake_git_repository_port_init (195-229)
  • gm_fake_git_repository_port_set_head_branch (247-261)
  • gm_fake_git_repository_port_last_update_ref (482-485)
  • gm_fake_git_repository_port_last_commit_message (472-475)
  • gm_fake_git_repository_port_dispose (231-237)
core/tests/fakes/logging/fake_logger_port.c (2)
  • gm_fake_logger_port_init (31-46)
  • gm_fake_logger_port_dispose (48-53)
core/tests/fakes/metrics/fake_metrics_port.c (2)
  • gm_fake_metrics_port_init (60-73)
  • gm_fake_metrics_port_dispose (75-80)
core/tests/fakes/diagnostics/fake_diagnostics_port.c (2)
  • gm_fake_diag_port_init (38-52)
  • gm_fake_diag_port_dispose (54-59)
core/src/ports/journal/journal_command_port.c (2)
  • gm_cmd_journal_port_init (50-65)
  • gm_cmd_journal_port_dispose (67-72)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/src/types/ulid.c (1)
  • gm_ulid_generate (118-126)
core/src/journal/reader.c (1)
  • gm_journal_read (357-361)
core/tests/fakes/fs/fake_fs_temp_port.c (1)
  • gm_fake_fs_temp_port_dispose (252-259)
core/tests/unit/test_cache_telemetry_emit.c (6)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/include/gitmind/security/memory.h (1)
  • gm_memset_safe (47-59)
core/tests/fakes/logging/fake_logger_port.c (2)
  • gm_fake_logger_port_init (31-46)
  • gm_fake_logger_port_dispose (48-53)
core/tests/fakes/metrics/fake_metrics_port.c (2)
  • gm_fake_metrics_port_init (60-73)
  • gm_fake_metrics_port_dispose (75-80)
core/src/app/cache/cache_rebuild_service.c (1)
  • gm_cache_rebuild_execute (494-676)
core/tests/fakes/fs/fake_fs_temp_port.c (1)
  • gm_fake_fs_temp_port_dispose (252-259)
core/tests/fakes/diagnostics/fake_diagnostics_port.h (1)
core/tests/fakes/diagnostics/fake_diagnostics_port.c (2)
  • gm_fake_diag_port_init (38-52)
  • gm_fake_diag_port_dispose (54-59)
core/src/journal/writer.c (5)
core/src/error/error.c (1)
  • gm_error_free (161-178)
core/include/gitmind/ports/diagnostic_port.h (1)
  • gm_diag_emit (37-46)
core/src/telemetry/log_format.c (1)
  • gm_log_format_render_default (71-107)
core/include/gitmind/ports/logger_port.h (1)
  • gm_logger_log (66-74)
core/include/gitmind/ports/metrics_port.h (2)
  • gm_metrics_timing_ms (72-79)
  • gm_metrics_counter_add (52-59)
apps/cli/main.c (1)
core/src/adapters/diagnostics/stderr_diagnostics_adapter.c (1)
  • gm_stderr_diagnostics_port_init (40-52)
core/tests/fakes/diagnostics/fake_diagnostics_port.c (1)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/src/journal/reader.c (5)
core/src/error/error.c (1)
  • gm_error_free (161-178)
core/include/gitmind/ports/diagnostic_port.h (1)
  • gm_diag_emit (37-46)
core/src/telemetry/log_format.c (1)
  • gm_log_format_render_default (71-107)
core/include/gitmind/ports/logger_port.h (1)
  • gm_logger_log (66-74)
core/include/gitmind/ports/metrics_port.h (2)
  • gm_metrics_timing_ms (72-79)
  • gm_metrics_counter_add (52-59)
core/tests/fakes/git/fake_git_repository_port.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_journal_nff_retry.c (4)
core/tests/fakes/diagnostics/fake_diagnostics_port.c (2)
  • gm_fake_diag_port_init (38-52)
  • gm_fake_diag_port_dispose (54-59)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/src/types/ulid.c (1)
  • gm_ulid_generate (118-126)
core/src/journal/writer.c (1)
  • gm_journal_append (436-440)
core/src/app/cache/cache_rebuild_service.c (6)
core/include/gitmind/ports/diagnostic_port.h (1)
  • gm_diag_emit (37-46)
core/include/gitmind/ports/logger_port.h (1)
  • gm_logger_log (66-74)
core/src/telemetry/log_format.c (1)
  • gm_log_format_render_default (71-107)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/include/gitmind/ports/metrics_port.h (3)
  • gm_metrics_timing_ms (72-79)
  • gm_metrics_counter_add (52-59)
  • gm_metrics_gauge_set (62-69)
core/src/error/error.c (1)
  • gm_error_free (161-178)
🔇 Additional comments (19)
core/tests/unit/test_cache_query.c (1)

72-72: LGTM: Repository initialization change aligns with CI parity goals.

Switching from bare to non-bare repository initialization is safe for this test, as the subsequent operations (branch creation, commits, cache queries) do not depend on bare repository semantics.

core/tests/unit/test_cache_branch_limits.c (1)

96-96: LGTM: Repository initialization change aligns with CI parity goals.

Switching from bare to non-bare repository initialization is safe for this test, as the subsequent operations (branch creation, commits, cache rebuilds) do not depend on bare repository semantics.

core/tests/unit/test_cli_json_env.c (2)

8-10: Conditional putenv declaration is acceptable for portability.

The conditional declaration of putenv for non-Windows platforms is reasonable for ensuring portability, though some compilers may issue warnings about implicit declarations.


20-22: Verify test isolation and side effects.

The test modifies the process environment, which could affect other tests if they run in the same process. While the environment change is scoped to this process and implicitly cleaned up on exit, consider whether this test should:

  1. Be run in isolation (separate process)
  2. Clean up the environment variable explicitly
  3. Document the side effect

Based on the test framework's execution model, verify that this test runs in isolation or that subsequent tests are not affected by the modified environment.

core/tests/fakes/git/fake_git_repository_port.c (1)

801-801: Retain default parent_count = 0; tests in test_hook_augment.c explicitly call gm_fake_git_repository_port_set_commit_parents to configure parents.

Likely an incorrect or invalid review comment.

core/include/gitmind/journal/internal/read_decoder.h (1)

4-18: Header looks umbrella-safe; API surface LGTM

Includes are minimal, guard and extern "C" present; types resolved.

Also applies to: 26-32

core/tests/unit/test_diagnostics_port.c (3)

40-56: LGTM!

The test setup correctly initializes fakes and stubs without direct I/O or global state. The use of fakes aligns with unit testing guidelines.


57-75: LGTM!

The test execution and assertions correctly verify that diagnostic events are emitted during cache rebuild failures. The event name checks cover the expected failure scenarios.


77-81: LGTM!

Cleanup is properly handled, and the success output follows the expected test pattern.

core/src/domain/journal/read_decoder.c (2)

47-60: LGTM!

The function correctly uses gm_memcpy_span and gm_strcpy_safe for memory and string operations, following coding guidelines.


62-107: LGTM!

The decoder function correctly implements fallback logic between attributed and basic formats, with proper input validation and error handling using the gm_result_void_t pattern.

core/src/journal/writer.c (6)

46-81: LGTM!

The addition of app_ctx to journal_ctx_t enables diagnostics integration without breaking existing functionality.


97-105: LGTM!

The refactoring to use gm_journal_encode_message simplifies the code while maintaining proper error handling and cleanup.


131-183: LGTM!

The changes correctly handle the first-commit case by treating GM_ERR_NOT_FOUND as empty history, and the use of gm_journal_build_commit_plan provides better structure.


200-255: LGTM!

The diagnostic emissions provide valuable observability for commit creation and ref update failures, with proper null checks on app_ctx.


311-401: LGTM!

The telemetry integration correctly loads configuration, builds tags, captures timing, and emits metrics and logs. The implementation follows telemetry patterns and provides good observability.


474-496: LGTM!

The addition of the ref update step ensures the provided ref points to the newly created commit, with proper error propagation.

meson.build (2)

124-148: LGTM!

The new source files align with the PR objectives to add domain modules, telemetry, and adapters for the hexagonal architecture.


519-524: LGTM!

The new port headers are correctly added to the public header compilation checks, ensuring they can be included standalone.

Comment thread apps/cli/main.c
Comment thread core/src/app/cache/cache_rebuild_service.c
Comment thread core/src/domain/journal/read_decoder.c Outdated
Comment thread core/src/journal/writer.c
Comment thread core/tests/fakes/diagnostics/fake_diagnostics_port.c
Comment thread core/tests/unit/test_cli_json_env.c Outdated
Comment thread core/tests/unit/test_cli_json_env.c Outdated
Comment thread core/tests/unit/test_journal_e2e_libgit2.c
Comment thread core/tests/unit/test_journal_nff_retry.c

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
docs/risk/Risk_Register.md (1)

17-20: Fix mismatch: “Top 10 Risks” vs 12 entries; align TOC text/anchor with section

There are 12 risks (R1–R12) but the header says “Top 10 Risks”. Also TOC label says “Top Risks” while linking to “#top-10-risks”. Recommend making the section title stable (“Top Risks”) and updating the TOC anchor accordingly.

Apply this diff:

- - [Top Risks](#top-10-risks)
+ - [Top Risks](#top-risks)

-## Top 10 Risks
+## Top Risks

Alternatively, if you intend exactly 10 items, trim to 10 and keep the existing anchors/text in sync. As per coding guidelines.

Also applies to: 25-26

docs/README.md (1)

27-27: Fix stale link in docs/README.md
Replace the removed “Journal Architecture Pivot” link with “Journal Architecture” pointing to the existing architecture/journal-architecture.md:

-- Start here if you’re new: [Journal Architecture Pivot](architecture/journal-architecture-pivot.md)
+- Start here if you’re new: [Journal Architecture](architecture/journal-architecture.md)
core/tests/integration/test_cache_query.c (1)

139-159: Fix dispose order and double-dispose of fs_temp_port

fs_temp_port is disposed before gm_fs_temp_port_remove_tree, risking use-after-free; also disposed twice. Remove the tree first, then dispose once.

Apply:

-    git_repository *saved_repo = repo;
-    if (ctx.fs_temp_port_dispose != NULL) {
-        ctx.fs_temp_port_dispose(&ctx.fs_temp_port);
-    }
-    if (ctx.git_repo_port_dispose != NULL) {
-        ctx.git_repo_port_dispose(&ctx.git_repo_port);
-    }
-    assert(repo == saved_repo);
+    git_repository *saved_repo = repo;
+    if (ctx.git_repo_port_dispose != NULL) {
+        ctx.git_repo_port_dispose(&ctx.git_repo_port);
+    }
     git_repository_free(repo);
     repo = NULL;
-    gm_result_void_t rm_rc =
-        gm_fs_temp_port_remove_tree(&ctx.fs_temp_port, repo_path);
+    gm_result_void_t rm_rc =
+        gm_fs_temp_port_remove_tree(&ctx.fs_temp_port, repo_path);
     if (!rm_rc.ok) {
         if (rm_rc.u.err != NULL) {
             gm_error_free(rm_rc.u.err);
         }
     }
-    if (ctx.fs_temp_port_dispose != NULL) {
-        ctx.fs_temp_port_dispose(&ctx.fs_temp_port);
-    }
+    if (ctx.fs_temp_port_dispose != NULL) {
+        ctx.fs_temp_port_dispose(&ctx.fs_temp_port);
+    }
♻️ Duplicate comments (1)
meson.build (1)

440-446: Resolved: test_journal_port now registered

Previously flagged missing registration is fixed; test_journal_port is defined and registered.

Also applies to: 493-494

🧹 Nitpick comments (8)
docs/README.md (3)

21-21: TOC nesting is inaccurate; make “Docs Conventions” a top‑level entry

“Docs Conventions” is not a child of “Getting Started”. Promote it to top‑level.

-  - [Docs Conventions](#docs-conventions)
+- [Docs Conventions](#docs-conventions)

52-53: Fix top‑level bullet indentation for “CLI (deferred)”

Align the top‑level bullet with the others; keep the explanatory sub‑bullet indented.

- - CLI (deferred)
+- CLI (deferred)
   - CLI docs are being restructured as part of the hexagonal migration and will return in a future update.

84-92: Fence the YAML example to satisfy markdownlint and prevent accidental parsing

The front‑matter example should be in a fenced code block (yaml) to avoid thematic breaks from raw --- and to pass MD linting.

-    ---
-    title: Page Title
-    description: One-line summary
-    audience: [developers]
-    domain: [architecture]
-    tags: [journal, cache]
-    status: stable
-    last_updated: 2025-09-15
-    ---
+```yaml
+---
+title: Page Title
+description: One-line summary
+audience: [developers]
+domain: [architecture]
+tags: [journal, cache]
+status: stable
+last_updated: 2025-09-15
+---
+```
core/tests/integration/test_journal_mixed_cbor.c (1)

10-15: Remove duplicate include of gitmind/error.h

gitmind/error.h is included twice (Line 10 and Line 13). Drop the second include to keep IWYU clean.

core/tests/unit/test_journal_e2e_libgit2.c (1)

186-194: Dispose fake logger/metrics ports to avoid leaks

Release fake port allocations during cleanup.

     gm_cmd_journal_port_dispose(&jport);
     if (ctx.git_repo_port_dispose) ctx.git_repo_port_dispose(&ctx.git_repo_port);
     git_repository_free(repo);
+    gm_fake_logger_port_dispose(&ctx.logger_port);
+    gm_fake_metrics_port_dispose(&ctx.metrics_port);
     gm_result_void_t rm_repo = gm_fs_temp_port_remove_tree(&ctx.fs_temp_port, repo_dir);
     assert(rm_repo.ok);
     if (ctx.fs_temp_port_dispose) ctx.fs_temp_port_dispose(&ctx.fs_temp_port);
     git_libgit2_shutdown();
core/tests/unit/test_cache_telemetry_emit.c (1)

34-43: Zero the output buffer on failure from sr_repository_path

Treat truncation as error and clear outputs. Ensure 'out' is nulled on error per guidelines.

 static gm_result_void_t sr_repository_path(void *self,
                                            gm_git_repository_path_kind_t kind,
                                            char *out, size_t out_size) {
     (void)kind;
     stub_repo_t *sr = (stub_repo_t *)self;
-    if (gm_strcpy_safe(out, out_size, sr->gitdir) != 0) {
-        return gm_err_void(GM_ERROR(GM_ERR_BUFFER_TOO_SMALL, "stub repo path too long"));
-    }
+    int rc = gm_strcpy_safe(out, out_size, sr->gitdir);
+    if (rc != GM_OK) {
+        if (out != NULL && out_size > 0) out[0] = '\0';
+        return gm_err_void(
+            GM_ERROR(GM_ERR_BUFFER_TOO_SMALL, "stub repo path too long"));
+    }
     return gm_ok_void();
 }

As per coding guidelines

core/tests/support/temp_repo_helpers.h (1)

7-17: Include <stdbool.h> and fix _getcwd size type on Windows to avoid -Wconversion

  • Use include-what-you-use: bool/true require <stdbool.h>.
  • On Windows, _getcwd expects int; passing size_t triggers -Wconversion (werror).

Apply:

 #include <errno.h>
 #include <stddef.h>
 #include <string.h>
+#include <stdbool.h>
+#include <limits.h>
@@
-    if (gm_test_getcwd(cwd, sizeof(cwd)) == NULL) {
+    #ifdef _WIN32
+    const int cwd_cap = (sizeof(cwd) > INT_MAX) ? INT_MAX : (int)sizeof(cwd);
+    if (gm_test_getcwd(cwd, cwd_cap) == NULL) {
+    #else
+    if (gm_test_getcwd(cwd, sizeof(cwd)) == NULL) {
+    #endif
         return gm_err_void(GM_ERROR(GM_ERR_IO_FAILED,
                                     "getcwd failed: %s", strerror(errno)));
     }

As per coding guidelines

Also applies to: 60-65

core/tests/integration/test_cache_branch_limits.c (1)

140-156: Duplicate disposal of fs_temp_port.

The fs_temp_port is disposed twice: once at lines 140–142 (before tree removal) and again at lines 154–156 (after tree removal). The second call is safe (checks for NULL dispose function) but redundant. Consider removing the first disposal and keeping only the final cleanup, or restructure to dispose once at the end.

Apply this diff to remove the first disposal:

-    if (ctx.fs_temp_port_dispose != NULL) {
-        ctx.fs_temp_port_dispose(&ctx.fs_temp_port);
-    }
     if (ctx.git_repo_port_dispose != NULL) {
         ctx.git_repo_port_dispose(&ctx.git_repo_port);
     }
📜 Review details

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 45cb56f and 2821584.

📒 Files selected for processing (27)
  • .github/workflows/auto-seed-review.yml (0 hunks)
  • core/include/gitmind/ports/cache_query_port.h (1 hunks)
  • core/src/app/cache/cache_rebuild_service.c (10 hunks)
  • core/src/domain/journal/read_decoder.c (1 hunks)
  • core/src/journal/reader.c (9 hunks)
  • core/src/journal/writer.c (11 hunks)
  • core/src/ports/cache/cache_query_port.c (1 hunks)
  • core/src/telemetry/config.c (1 hunks)
  • core/src/telemetry/log_format.c (1 hunks)
  • core/tests/fakes/diagnostics/fake_diagnostics_port.c (1 hunks)
  • core/tests/fakes/metrics/fake_metrics_port.c (1 hunks)
  • core/tests/integration/test_cache_branch_limits.c (4 hunks)
  • core/tests/integration/test_cache_meta.c (3 hunks)
  • core/tests/integration/test_cache_query.c (3 hunks)
  • core/tests/integration/test_cache_tree_size.c (3 hunks)
  • core/tests/integration/test_journal_mixed_cbor.c (3 hunks)
  • core/tests/integration/test_repo_build_tree.c (1 hunks)
  • core/tests/support/temp_repo_helpers.h (1 hunks)
  • core/tests/unit/test_cache_telemetry_emit.c (1 hunks)
  • core/tests/unit/test_cli_json_env.c (1 hunks)
  • core/tests/unit/test_journal_e2e_libgit2.c (1 hunks)
  • core/tests/unit/test_journal_nff_retry.c (1 hunks)
  • docs/README.md (2 hunks)
  • docs/operations/Telemetry_Config.md (1 hunks)
  • docs/requirements/Requirements.md (1 hunks)
  • docs/risk/Risk_Register.md (1 hunks)
  • meson.build (8 hunks)
💤 Files with no reviewable changes (1)
  • .github/workflows/auto-seed-review.yml
✅ Files skipped from review due to trivial changes (1)
  • docs/requirements/Requirements.md
🚧 Files skipped from review as they are similar to previous changes (8)
  • core/tests/unit/test_cli_json_env.c
  • core/tests/fakes/metrics/fake_metrics_port.c
  • core/src/telemetry/log_format.c
  • core/include/gitmind/ports/cache_query_port.h
  • docs/operations/Telemetry_Config.md
  • core/tests/unit/test_journal_nff_retry.c
  • core/src/domain/journal/read_decoder.c
  • core/src/telemetry/config.c
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{c,cc,cpp,cxx,h,hpp,hxx,m,mm}

📄 CodeRabbit inference engine (CLAUDE.md)

NEVER use NOLINT to suppress clang-tidy warnings; ALWAYS fix the underlying issue

Files:

  • core/tests/integration/test_cache_meta.c
  • core/tests/integration/test_cache_tree_size.c
  • core/tests/integration/test_journal_mixed_cbor.c
  • core/src/ports/cache/cache_query_port.c
  • core/tests/unit/test_cache_telemetry_emit.c
  • core/tests/integration/test_repo_build_tree.c
  • core/tests/support/temp_repo_helpers.h
  • core/tests/integration/test_cache_query.c
  • core/tests/unit/test_journal_e2e_libgit2.c
  • core/tests/integration/test_cache_branch_limits.c
  • core/tests/fakes/diagnostics/fake_diagnostics_port.c
  • core/src/journal/writer.c
  • core/src/journal/reader.c
  • core/src/app/cache/cache_rebuild_service.c
{core,src,apps,tests}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

{core,src,apps,tests}/**/*.{c,h}: Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths
Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required
Equality is OID-first; if both OIDs exist they must match; only fall back to SHA when OIDs are absent
Build refs via gm_build_ref and reject inputs that start with "refs/"
Language: C23 with warnings-as-errors; no VLAs, no shadowing; declare explicit prototypes
Formatting via .clang-format (LLVM style, 4 spaces, 80 cols, pointer alignment right); pre-commit runs clang-format
Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with t; header guards start with GITMIND
Includes: prefer specific headers; order/regroup per .clang-format; include-what-you-use
No new clang-tidy warnings; keep touched files tidy-clean
Surface failures via gm_result_t (and variants); ports must not return raw integers
Maintain one responsibility per translation unit where practical; split multi-concern files when touched
Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers
Zero output buffers before formatting/copying on error paths

Files:

  • core/tests/integration/test_cache_meta.c
  • core/tests/integration/test_cache_tree_size.c
  • core/tests/integration/test_journal_mixed_cbor.c
  • core/src/ports/cache/cache_query_port.c
  • core/tests/unit/test_cache_telemetry_emit.c
  • core/tests/integration/test_repo_build_tree.c
  • core/tests/support/temp_repo_helpers.h
  • core/tests/integration/test_cache_query.c
  • core/tests/unit/test_journal_e2e_libgit2.c
  • core/tests/integration/test_cache_branch_limits.c
  • core/tests/fakes/diagnostics/fake_diagnostics_port.c
  • core/src/journal/writer.c
  • core/src/journal/reader.c
  • core/src/app/cache/cache_rebuild_service.c
core/tests/**/*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests should use fakes only; integration tests may use real adapters but only inside Docker

Files:

  • core/tests/integration/test_cache_meta.c
  • core/tests/integration/test_cache_tree_size.c
  • core/tests/integration/test_journal_mixed_cbor.c
  • core/tests/unit/test_cache_telemetry_emit.c
  • core/tests/integration/test_repo_build_tree.c
  • core/tests/integration/test_cache_query.c
  • core/tests/unit/test_journal_e2e_libgit2.c
  • core/tests/integration/test_cache_branch_limits.c
  • core/tests/fakes/diagnostics/fake_diagnostics_port.c
core/src/ports/**

📄 CodeRabbit inference engine (AGENTS.md)

Default implementations for simple inbound coordinators that remain in C may live under core/src/ports/**

Files:

  • core/src/ports/cache/cache_query_port.c
core/src/**/{hooks,cache,journal}/**/*.{c,h}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid direct libgit2 usage; route repository/ref operations through gm_git_repository_port/gm_git_ref_port adapters

Files:

  • core/src/ports/cache/cache_query_port.c
  • core/src/journal/writer.c
  • core/src/journal/reader.c
  • core/src/app/cache/cache_rebuild_service.c
core/tests/unit/test_*.c

📄 CodeRabbit inference engine (AGENTS.md)

Unit tests live in core/tests/unit/ and are named test_.c; keep deterministic and isolated

Files:

  • core/tests/unit/test_cache_telemetry_emit.c
  • core/tests/unit/test_journal_e2e_libgit2.c
docs/**/*.md

📄 CodeRabbit inference engine (AGENTS.md)

docs/**/*.md: Docs must have front matter first, a single H1, a '## Table of Contents', and the title must match the H1
Add api_version field to API docs front matter
Place License/SPDX comments immediately after front matter in docs
README and other Markdown must comply with markdownlint rules: underscore emphasis/strong, blockquote spacing, code fence formatting, no inline HTML wrappers, heading punctuation

Files:

  • docs/README.md
  • docs/risk/Risk_Register.md
core/tests/fakes/**

📄 CodeRabbit inference engine (AGENTS.md)

Provide deterministic fakes/mocks/stubs for every outbound port under core/tests/fakes/** with harnesses verifying contract invariants

Files:

  • core/tests/fakes/diagnostics/fake_diagnostics_port.c
meson.build

📄 CodeRabbit inference engine (AGENTS.md)

Target C23 via Meson c2x and keep warnings-as-errors; register new unit test targets in meson.build

Files:

  • meson.build
🧠 Learnings (8)
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths

Applied to files:

  • core/tests/unit/test_cache_telemetry_emit.c
  • core/tests/unit/test_journal_e2e_libgit2.c
  • core/src/app/cache/cache_rebuild_service.c
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Do not use buffers sized GM_PATH_MAX*2; prefer GM_PATH_MAX and allocate if larger is required

Applied to files:

  • core/tests/unit/test_journal_e2e_libgit2.c
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to core/src/**/{hooks,cache,journal}/**/*.{c,h} : Avoid direct libgit2 usage; route repository/ref operations through gm_git_repository_port/gm_git_ref_port adapters

Applied to files:

  • core/tests/integration/test_cache_branch_limits.c
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Naming: functions/vars lower_snake_case with gm_ prefix; macros UPPER_SNAKE; types end with _t; header guards start with GITMIND_

Applied to files:

  • core/src/journal/writer.c
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Prefer OID types and helpers (gm_oid_t, git_oid_cmp via wrappers, gm_oid_to_hex); avoid direct libgit2 helpers in domain/application layers

Applied to files:

  • core/src/app/cache/cache_rebuild_service.c
📚 Learning: 2025-10-01T04:13:25.799Z
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to core/include/gitmind/ports/**/*.h : Define all inbound/outbound ports as headers only under core/include/gitmind/ports/** with POD structs and function-pointer vtables (no non-trivial inline behavior)

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: Applies to include/gitmind/**/*.h : Public, namespaced headers live under include/gitmind/

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: Applies to include/gitmind.h : Maintain umbrella API at include/gitmind.h

Applied to files:

  • meson.build
🧬 Code graph analysis (14)
core/tests/integration/test_cache_meta.c (1)
core/src/adapters/fs/posix_temp_adapter.c (1)
  • gm_posix_fs_temp_port_create (628-653)
core/tests/integration/test_cache_tree_size.c (1)
core/src/adapters/fs/posix_temp_adapter.c (1)
  • gm_posix_fs_temp_port_create (628-653)
core/tests/integration/test_journal_mixed_cbor.c (1)
core/src/adapters/fs/posix_temp_adapter.c (1)
  • gm_posix_fs_temp_port_create (628-653)
core/src/ports/cache/cache_query_port.c (2)
core/src/cache/query.c (3)
  • gm_cache_query_fanout (392-396)
  • gm_cache_query_fanin (399-403)
  • gm_cache_stats (415-448)
core/src/ports/cache/cache_build_port.c (1)
  • gm_result_void_t (42-57)
core/tests/unit/test_cache_telemetry_emit.c (6)
core/include/gitmind/util/memory.h (2)
  • gm_strcpy_safe (113-138)
  • gm_memcpy_span (32-47)
core/include/gitmind/security/memory.h (1)
  • gm_memset_safe (47-59)
core/tests/fakes/logging/fake_logger_port.c (2)
  • gm_fake_logger_port_init (31-46)
  • gm_fake_logger_port_dispose (48-53)
core/tests/fakes/metrics/fake_metrics_port.c (2)
  • gm_fake_metrics_port_init (94-107)
  • gm_fake_metrics_port_dispose (109-114)
core/src/app/cache/cache_rebuild_service.c (1)
  • gm_cache_rebuild_execute (494-769)
core/tests/fakes/fs/fake_fs_temp_port.c (1)
  • gm_fake_fs_temp_port_dispose (252-259)
core/tests/integration/test_repo_build_tree.c (2)
core/src/adapters/fs/posix_temp_adapter.c (1)
  • gm_posix_fs_temp_port_create (628-653)
core/src/adapters/git/libgit2_repository_port.c (1)
  • gm_libgit2_repository_port_create (1111-1139)
core/tests/support/temp_repo_helpers.h (1)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/tests/integration/test_cache_query.c (2)
core/src/adapters/fs/posix_temp_adapter.c (1)
  • gm_posix_fs_temp_port_create (628-653)
core/src/error/error.c (1)
  • gm_error_free (161-178)
core/tests/unit/test_journal_e2e_libgit2.c (8)
core/tests/integration/test_repo_build_tree.c (1)
  • write_file (18-25)
core/src/adapters/fs/posix_temp_adapter.c (1)
  • gm_posix_fs_temp_port_create (628-653)
core/src/adapters/git/libgit2_repository_port.c (1)
  • gm_libgit2_repository_port_create (1111-1139)
core/tests/fakes/logging/fake_logger_port.c (1)
  • gm_fake_logger_port_init (31-46)
core/tests/fakes/metrics/fake_metrics_port.c (1)
  • gm_fake_metrics_port_init (94-107)
core/src/ports/journal/journal_command_port.c (2)
  • gm_cmd_journal_port_init (50-65)
  • gm_cmd_journal_port_dispose (67-72)
core/src/edge/edge.c (1)
  • gm_edge_create (56-107)
core/src/journal/reader.c (1)
  • gm_journal_read (458-462)
core/tests/integration/test_cache_branch_limits.c (2)
core/src/adapters/fs/posix_temp_adapter.c (1)
  • gm_posix_fs_temp_port_create (628-653)
core/src/error/error.c (1)
  • gm_error_free (161-178)
core/tests/fakes/diagnostics/fake_diagnostics_port.c (1)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/src/journal/writer.c (5)
core/src/error/error.c (1)
  • gm_error_free (161-178)
core/include/gitmind/ports/diagnostic_port.h (1)
  • gm_diag_emit (37-46)
core/src/telemetry/log_format.c (1)
  • gm_log_format_render_default (71-121)
core/include/gitmind/ports/logger_port.h (1)
  • gm_logger_log (66-74)
core/include/gitmind/ports/metrics_port.h (2)
  • gm_metrics_timing_ms (72-79)
  • gm_metrics_counter_add (52-59)
core/src/journal/reader.c (6)
core/src/error/error.c (1)
  • gm_error_free (161-178)
core/include/gitmind/ports/diagnostic_port.h (1)
  • gm_diag_emit (37-46)
core/include/gitmind/ports/logger_port.h (1)
  • gm_logger_log (66-74)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/src/telemetry/log_format.c (1)
  • gm_log_format_render_default (71-121)
core/include/gitmind/ports/metrics_port.h (2)
  • gm_metrics_timing_ms (72-79)
  • gm_metrics_counter_add (52-59)
core/src/app/cache/cache_rebuild_service.c (6)
core/include/gitmind/ports/diagnostic_port.h (1)
  • gm_diag_emit (37-46)
core/src/error/error.c (1)
  • gm_error_free (161-178)
core/include/gitmind/ports/logger_port.h (1)
  • gm_logger_log (66-74)
core/src/telemetry/log_format.c (1)
  • gm_log_format_render_default (71-121)
core/include/gitmind/util/memory.h (1)
  • gm_strcpy_safe (113-138)
core/include/gitmind/ports/metrics_port.h (3)
  • gm_metrics_timing_ms (72-79)
  • gm_metrics_counter_add (52-59)
  • gm_metrics_gauge_set (62-69)
🔇 Additional comments (16)
docs/risk/Risk_Register.md (2)

10-11: SPDX and copyright placement LGTM

License/SPDX comments are correctly placed immediately after front matter. No further changes needed.
As per coding guidelines.


15-15: TOC heading conforms

“## Table of Contents” heading is present and correctly leveled.
As per coding guidelines.

docs/README.md (2)

10-11: SPDX/license placement looks correct

License and copyright comments are immediately after front matter, per docs guidelines.


15-15: TOC present and correctly headed

The “## Table of Contents” section is present and positioned after the H1.

core/tests/fakes/diagnostics/fake_diagnostics_port.c (1)

12-70: Emit path handles truncation and invalid args correctly

Good: validates inputs, checks gm_strcpy_safe results, zeros partial outputs, and returns structured errors. Capacity capping is clear and safe.

core/tests/unit/test_journal_e2e_libgit2.c (1)

173-177: Confirm NULL branch semantics for gm_journal_read

Passing branch=NULL relies on reader defaulting to a sensible branch. Please confirm this is supported; otherwise pass an explicit branch (e.g., "main") to avoid undefined behavior.

core/tests/integration/test_repo_build_tree.c (1)

89-97: Ignore cast warning gm_oid_t is a direct alias of git_oid, so casting &tree_oid to git_oid* is safe.

Likely an incorrect or invalid review comment.

core/tests/integration/test_cache_tree_size.c (1)

32-38: Temp FS/repo setup and teardown LGTM

Isolated temp repo creation, use, and cleanup are correct. Good assertions and disposer usage.

Also applies to: 39-44, 46-47, 127-131

core/tests/integration/test_cache_meta.c (1)

51-64: Temp repo orchestration and cleanup LGTM

Uses gm_posix_fs_temp_port and gm_test_make_temp_repo_dir correctly; cleanup order is sound.

Also applies to: 66-67, 87-91

core/src/ports/cache/cache_query_port.c (1)

1-102: LGTM!

The port implementation follows best practices:

  • Defensive zeroing of output parameters before validation (lines 54–59)
  • Consistent error handling with descriptive messages
  • Proper state allocation/disposal lifecycle
  • Clean separation of concerns via vtable dispatch
core/src/journal/writer.c (2)

39-42: LGTM! _Static_assert prevents CLOCKS_PER_MS division by zero.

The _Static_assert at lines 39–40 ensures CLOCKS_PER_SEC >= 1000, preventing the division-by-zero issue previously flagged. This is a robust compile-time check.


323-334: No free needed after gm_fs_temp_port_canonicalize_ex
canonicalize_impl returns the internal state buffer (state->scratch), not malloc’ed memory; freeing is unnecessary.

Likely an incorrect or invalid review comment.

core/src/app/cache/cache_rebuild_service.c (3)

513-601: LGTM! Telemetry and logging properly instrumented.

The telemetry setup and logging paths correctly:

  • Capture and free errors from gm_telemetry_cfg_load (lines 515–537)
  • Capture and free errors from gm_telemetry_build_tags (lines 556–566)
  • Check formatter results and fall back on errors (lines 583–594)
  • Initialize buffers and check for empty messages before logging

This addresses the past review concerns about honoring gm_telemetry_* return values.


686-697: LGTM! gm_snprintf returns properly checked.

The code now checks gm_snprintf returns and treats truncation/errors as failures, returning GM_ERR_BUFFER_TOO_SMALL. This satisfies the coding guideline requirement.

As per coding guidelines

Also applies to: 733-739


544-555: Don’t free repo_canon; it’s an internal buffer
gm_fs_temp_port_canonicalize_ex returns state->scratch (a fixed‐size array in gm_posix_fs_state_t), not a malloc’d string—no free required.

Likely an incorrect or invalid review comment.

core/src/journal/reader.c (1)

384-390: Check gm_snprintf return in fallback path.

The fallback gm_snprintf at line 384 is not checked per coding guidelines. Treat truncation as an error by verifying the return value.

As per coding guidelines

Apply this diff:

         if (!fmt_rc.ok) {
             if (fmt_rc.u.err != NULL) gm_error_free(fmt_rc.u.err);
             int alt = gm_snprintf(msg, sizeof(msg),
                                   "event=journal_read_start branch=%s mode=%s",
                                   resolved_branch, mode);
             if (alt < 0 || (size_t)alt >= sizeof(msg)) {
                 msg[0] = '\0';
             }
         }
⛔ Skipped due to learnings
Learnt from: CR
PR: neuroglyph/git-mind#0
File: AGENTS.md:0-0
Timestamp: 2025-10-01T04:13:25.799Z
Learning: Applies to {core,src,apps,tests}/**/*.{c,h} : Use gm_snprintf/gm_strcpy_safe/gm_memcpy_span for all string/memory ops; check returns and treat truncation as error; zero outputs on failure paths

Comment thread core/src/journal/reader.c
Comment thread core/src/journal/reader.c
Comment thread core/src/journal/reader.c
Comment thread core/src/journal/writer.c
Comment thread core/src/journal/writer.c
Comment thread core/tests/support/temp_repo_helpers.h
Comment thread docs/README.md
Comment on lines +49 to +50
- [Journal Architecture](architecture/journal-architecture.md)
- [Cache Architecture](architecture/cache-architecture.md)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

New architecture links look good; verify they resolve

Links align with PR intent. Please confirm the files exist to keep link hygiene green.


🏁 Script executed:

#!/bin/bash
set -euo pipefail
for f in docs/architecture/journal-architecture.md docs/architecture/cache-architecture.md; do
  if [[ -f "$f" ]]; then
    echo "OK: $f"
    # Check each has a single H1
    rg -n '^# ' "$f" | wc -l | awk -v f="$f" '{print "H1 count in " f ": " $0}'
  else
    echo "MISSING: $f"
  fi
done

Length of output: 201


Enforce a single H1 per architecture doc: docs/architecture/journal-architecture.md contains 8 H1 headings; convert all but the main title to H2+ to maintain one H1.

🤖 Prompt for AI Agents
In docs/README.md around lines 49 to 50: the linked architecture doc
docs/architecture/journal-architecture.md currently contains 8 H1 headings; open
that file and retain only the main document title as a single H1, converting all
other top-level headings from "# " to "## " (or deeper levels like "### " where
appropriate) so they become H2+; ensure the main title remains the first H1,
update any TOC or cross-references if needed, and run the markdown
linter/preview to verify only one H1 remains.

@flyingrobots
flyingrobots merged commit e56d30b into main Oct 9, 2025
5 checks passed
@flyingrobots
flyingrobots deleted the feat/hex-ports-ci-green branch October 9, 2025 02:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant