Skip to content

feat(review): add bounded review-context packets - #128

Merged
PatrickSys merged 24 commits into
masterfrom
agent/review-context-v1
Aug 22, 2026
Merged

feat(review): add bounded review-context packets#128
PatrickSys merged 24 commits into
masterfrom
agent/review-context-v1

Conversation

@PatrickSys

@PatrickSys PatrickSys commented Aug 22, 2026

Copy link
Copy Markdown
Owner

What

Adds the first review-oriented vertical slice to codebase-context without importing or relying on the abandoned private context-kit implementation.

  • new codebase-context-review binary
  • exact committed git range -> bounded review-context-v1 packet
  • changed-file status, diff stats, rename/binary handling, exact diff SHA-256
  • NUL-safe git filename parsing
  • bounded lexical identifiers derived from changed lines
  • bounded existing search_codebase retrieval + edit preflight metadata
  • current convention/pattern snapshot
  • explicit limits and warnings
  • clean-worktree + checked-out-head invariant so diff and repository context describe the same committed source state
  • default incremental index refresh; --no-index for controlled benchmark runs
  • unit coverage for parsing, identifier ranking, bounds, exact fingerprinting, and packet assembly
  • engineering contract/limitations/evaluation plan in docs/review-context.md

Reproducibility boundary

The git envelope, identifier extraction, bounds, and query derivation are deterministic. Related-context ranking is reproducible only under a frozen codebase-context version, index, embedding/reranking configuration, and runtime dependencies. The docs state that explicitly rather than treating semantic retrieval as environment-independent.

Non-claims

This does not claim better review quality. It does not call an LLM or post comments. The packet is a context input so raw-diff vs enriched-context reviewer runs can be evaluated without mixing retrieval and reasoning.

The next gate is evidence: freeze a small public review task set and compare the same reviewer/model under fixed budgets before adding reviewer-agent orchestration.

Safety / scope

  • no employer/private code or context-kit history copied into this branch
  • local-first; git + existing local index only
  • committed refs only in v1
  • bounded queries/results/snippets
  • no silent truncation of the raw diff fingerprint input

@greptile-apps

greptile-apps Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds a new CLI that turns a committed Git range into a bounded review-context packet, together with packet assembly utilities, tests, package wiring, and documentation.

  • Resolves Git refs and collects changed-file metadata, patches, statistics, identifiers, and a raw-diff fingerprint.
  • Runs bounded code searches and convention retrieval through the existing local index.
  • Exposes human-readable and JSON output through the new codebase-context-review binary.
  • Documents the packet contract, limits, evaluation plan, and current limitations.

Confidence Score: 3/5

The pull request should not merge until packet construction is pinned to resolved commits and changed-file parsing preserves valid Git filenames.

Mutable refs can make the packet's recorded commits disagree with its diff-derived content, while line-oriented name-status parsing can omit or misattribute files with Git-special names.

Files Needing Attention: src/review-cli.ts, src/review-context.ts, docs/review-context.md

Important Files Changed

Filename Overview
src/review-cli.ts Adds the executable workflow and local indexing/tool context, but repeated diffs use mutable refs rather than the resolved commit SHAs.
src/review-context.ts Adds deterministic packet assembly, identifier ranking, bounds, and result compaction, but name-status parsing does not preserve all valid Git paths.
tests/review-context.test.ts Covers core parsing, ranking, bounding, fingerprinting, and packet assembly, but not mutable refs or Git-special filenames.
docs/review-context.md Documents the new workflow and appropriately limits its claims, but introduces a new Markdown file contrary to repository documentation governance.
package.json Publishes the new executable and documentation file through the package manifest.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    A[Base and head refs] --> B[Resolve commit SHAs]
    A --> C[Collect Git range and per-file diffs]
    C --> D[Parse changed files and identifiers]
    D --> E[Build bounded search queries]
    E --> F[Search local index]
    G[Team pattern lookup] --> H[Review-context packet]
    B --> H
    C --> H
    D --> H
    F --> H
Loading

Reviews (1): Last reviewed commit: "docs(review): document review context co..." | Re-trigger Greptile

Comment thread src/review-cli.ts Outdated
const rootPath = path.resolve(gitRoot);
const baseCommit = resolveCommit(rootPath, options.base);
const headCommit = resolveCommit(rootPath, options.head);
const range = `${options.base}...${options.head}`;

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.

P1 Mutable refs break packet identity

When the base or head ref moves during packet construction, the separate Git commands resolve different commits while refs.baseCommit and refs.headCommit retain the earlier SHAs, causing the fingerprint, changed-file data, and per-file patches to describe a different or internally inconsistent range.

Suggested change
const range = `${options.base}...${options.head}`;
const range = `${baseCommit}...${headCommit}`;

Comment thread src/review-context.ts
Comment on lines +160 to +164
head: string;
baseCommit: string;
headCommit: string;
rawDiff: string;
changedFiles: ChangedFileDescriptor[];

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.

P1 Line parsing corrupts Git paths

When a committed filename contains tabs, newlines, significant surrounding whitespace, or characters represented through Git quoting, trimming and splitting non-NUL --name-status output changes or splits the path; the subsequent per-file diff then omits or misattributes that file even though it remains included in the raw-diff fingerprint.

Comment thread docs/review-context.md
@@ -0,0 +1,117 @@
# Review context

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.

P2 New document violates docs constraint

This change adds another Markdown document without deleting or updating an existing Markdown document to make room, increasing the documentation set contrary to the repository's explicit maintenance constraint.

Context Used: AGENTS.md (source)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e728e938b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/review-cli.ts
'--find-renames',
range,
'--',
file.path

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Include both paths when collecting rename patches

For every renamed file, this pathspec includes only the destination path. I reproduced this in a temporary repository: although git diff -h documents -M as detecting renames, git diff --find-renames base...head -- new.txt rendered a 100% rename as a newly added file. Consequently, rename-only changes report every unchanged line as an addition and extract identifiers from unchanged content, corrupting packet statistics and evaluation signals; include previousPath as well or split the unfiltered diff.

Useful? React with 👍 / 👎.

Comment thread docs/review-context.md
@@ -0,0 +1,117 @@
# Review context

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Archive a Markdown file before adding this document

This commit introduces a new Markdown document without archiving or deleting another Markdown file, directly violating the repository's documentation constraint. Update an existing document or archive one before adding this file.

AGENTS.md reference: AGENTS.md:L206-L211

Useful? React with 👍 / 👎.

Comment thread src/review-cli.ts
return parsed;
}

function parseArgs(argv: string[]): ReviewCliOptions | undefined {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep the review CLI implementation in src/cli.ts

This starts a separate CLI implementation containing argument parsing, Git orchestration, indexing, and output formatting, while the repository explicitly requires CLI code to live in src/cli.ts. Move this implementation there, leaving at most a thin executable shim for the additional binary.

AGENTS.md reference: AGENTS.md:L226-L231

Useful? React with 👍 / 👎.

Comment thread src/review-cli.ts
parseToolJson<SearchResponse>(
await dispatchTool(
'search_codebase',
{ query, includeSnippets: true, intent: 'edit', limit },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Make snippets opt-in for JSON packets

When consumers request the machine-readable packet, snippets are always enabled and the defaults can include up to 24 snippets of 1,200 characters each—many thousands of tokens before other metadata—with no summary-only option. Default to summaries and paths or require an explicit snippet flag so review output respects the repository's response-budget and default-output requirements.

AGENTS.md reference: AGENTS.md:L220-L224

Useful? React with 👍 / 👎.

Comment thread src/review-cli.ts
),
loadConventions: async () =>
parseToolJson<PatternResponse>(
await dispatchTool('get_team_patterns', { category: 'all' }, toolContext),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Bound the convention snapshot

In repositories with many stored team memories, get_team_patterns with category: 'all' returns every matching memory and this response is copied wholesale into the packet without a count or character limit. Thus the advertised bounded packet can grow arbitrarily even when query, result, and snippet limits are respected; compact or cap this convention payload and report truncation.

AGENTS.md reference: AGENTS.md:L220-L224

Useful? React with 👍 / 👎.

Comment thread src/review-cli.ts
throw new Error(`${operation} returned invalid JSON`);
}

if (response.isError) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Reject tool error payloads before storing conventions

When intelligence.json is missing or corrupt, get_team_patterns returns a JSON {status: 'error', ...} payload without setting isError; this check therefore accepts it as a valid PatternResponse, and the packet stores the error object under conventions without adding a warning. Validate the operation's status/schema so failed convention retrieval is explicitly reported rather than presented as context.

AGENTS.md reference: AGENTS.md:L191-L194

Useful? React with 👍 / 👎.

Comment thread src/review-context.ts
Comment on lines +176 to +180
for (const rawLine of output.split(/\r?\n/)) {
const line = rawLine.trim();
if (!line) continue;

const parts = line.split('\t');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Parse name-status records with NUL delimiters

For valid repository paths containing tabs, newlines, or trailing spaces, newline/tab parsing either receives Git's quoted pseudo-path or strips part of the filename with trim(), after which the per-file diff lookup targets a nonexistent path and produces an empty patch. git diff -h documents -z as producing NUL-terminated diff-raw output; invoke --name-status -z and parse NUL-separated fields to preserve filenames exactly.

Useful? React with 👍 / 👎.

@PatrickSys PatrickSys changed the title feat(review): add deterministic review-context packets feat(review): add bounded review-context packets Aug 22, 2026
@PatrickSys
PatrickSys merged commit 2c56b10 into master Aug 22, 2026
3 checks passed
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