Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 54 additions & 24 deletions .github/workflows/claude-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,47 +33,77 @@ jobs:
claude-review-with-tracking:
runs-on: ubuntu-latest

# Only run for trusted authors or when explicitly mentioned by them
# Run on PRs or when explicitly triggered via comments
if: |
(
github.event_name == 'pull_request_target' &&
(
github.event.pull_request.author_association == 'OWNER' ||
github.event.pull_request.author_association == 'MEMBER' ||
github.event.pull_request.author_association == 'COLLABORATOR'
)
) ||
github.event_name == 'pull_request_target' ||
(
(github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment') &&
contains(github.event.comment.body, '@claude') &&
(
github.event.comment.author_association == 'OWNER' ||
github.event.comment.author_association == 'MEMBER' ||
github.event.comment.author_association == 'COLLABORATOR'
)
contains(github.event.comment.body, '@claude')
) ||
(
github.event_name == 'pull_request_review' &&
contains(github.event.review.body, '@claude') &&
(
github.event.review.author_association == 'OWNER' ||
github.event.review.author_association == 'MEMBER' ||
github.event.review.author_association == 'COLLABORATOR'
)
contains(github.event.review.body, '@claude')
)

steps:
# Checkout PR Branch (for comments)
- name: Resolve PR Ref
id: resolve-pr-ref
if: github.event_name == 'issue_comment' && github.event.issue.pull_request
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
PR_NUMBER=${{ github.event.issue.number }}
echo "Resolving HEAD SHA and Repo for PR #$PR_NUMBER..."

# Get SHA and Repo Name using gh
# Note: Using awk implies fields are space-separated and don't contain spaces themselves,
# which is safe for git SHAs and "owner/repo" strings.
# We use a conditional template to handle cases where the head repository (fork) might be deleted/null.
RESOLVED=$(gh pr view $PR_NUMBER --repo ${{ github.repository }} --json headRefOid,headRepository --template '{{.headRefOid}} {{if .headRepository}}{{.headRepository.owner.login}}/{{.headRepository.name}}{{else}}MISSING{{end}}')

PR_SHA=$(echo "$RESOLVED" | awk '{print $1}')
PR_REPO=$(echo "$RESOLVED" | awk '{print $2}')

echo "Resolved SHA: $PR_SHA"
echo "Resolved Repo: $PR_REPO"

# Check for valid repository format (owner/repo)
if [ "$PR_REPO" = "MISSING" ] || [[ "$PR_REPO" != *"/"* ]]; then
echo "Warning: Could not resolve source repository (fork might be deleted). Falling back to base repository."
PR_REPO="${{ github.repository }}"
fi

echo "pr_sha=$PR_SHA" >> $GITHUB_OUTPUT
echo "pr_repo=$PR_REPO" >> $GITHUB_OUTPUT

# Checkout the repository at the appropriate commit for review
- name: Checkout repository
uses: actions/checkout@v6
with:
# Checkout the PR source repository (fork) to ensure branches exist for the action
repository: ${{ steps.resolve-pr-ref.outputs.pr_repo || github.event.pull_request.head.repo.full_name || github.repository }}
# Use PR head SHA for pull_request_target to review the actual PR code
# For comment events, this will default to the base branch (PR context is inferred by Claude action)
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 1
ref: ${{ steps.resolve-pr-ref.outputs.pr_sha || github.event.pull_request.head.sha || github.sha }}
fetch-depth: 20

# Fix git ref access for claude-code-action PR branch checkout
# The action internally runs: git fetch origin pull/N/head:pr-N
# This can fail for two reasons:
# 1. Under git protocol v2, refs/pull/* may not be discoverable if not in
# the configured fetch refspec (causes "couldn't find remote ref")
# 2. If a local branch pr-N already exists and is checked out, git refuses
# to fetch into it (causes "refusing to fetch into branch")
# Adding refs/pull/*/head to the fetch refspec solves issue 1, and we avoid
# creating local branches to prevent issue 2.
- name: Configure git for PR ref access
run: |
git config --add remote.origin.fetch '+refs/pull/*/head:refs/remotes/origin/pull/*/head'

# Invoke Claude to perform an automated PR review with progress tracking
- name: PR Review with Progress Tracking
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
Expand Down
116 changes: 110 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## What This Repository Is

git-internal is a high-performance Rust library for encoding/decoding Git internal objects and Pack files. It supports large monorepo-scale repositories with delta compression, multi-pack indexing, streaming I/O, and both sync/async APIs.
git-internal is a high-performance Rust library for encoding/decoding Git internal objects, Pack files, and AI-assisted development objects. It supports large monorepo-scale repositories with delta compression, multi-pack indexing, streaming I/O, and both sync/async APIs. Beyond the standard Git object model (Blob, Tree, Commit, Tag), it provides a structured AI object model (Intent, Plan, Task, Run, PatchSet, Evidence, Decision, etc.) that captures the full lifecycle of AI-driven code changes.

## Build & Test Commands

Expand All @@ -19,13 +19,21 @@ cargo test <test_name> # Run specific test
cargo test -- --nocapture # Show output

# Lint & Format
cargo fmt # Format code
cargo +nightly fmt # Format code (requires nightly)
cargo +nightly fmt --check # Check formatting without modifying
cargo clippy # Lint (treat warnings as errors for new code)

# Check all targets compile
cargo build --all-targets
```

## Git Commands

```bash
git commit -a -s -S -m"" # Commit
git push --force
```

## Architecture Overview

```
Expand All @@ -36,17 +44,87 @@ internal/pack (encode/decode/waitlist/cache/idx)
⇅ internal/object/index/metadata
⇅ delta / zstdelta / diff

internal/object
├── Standard: blob, tree, commit, tag, note
├── AI objects: intent, plan, task, run, patchset,
│ evidence, decision, provenance, tool, context, pipeline
└── Shared: types (Header, ActorRef, ObjectType), integrity, signature

hash.rs / utils.rs / errors.rs (shared infrastructure)
```

**Core hub**: `internal/pack` - decodes/encodes packs, manages cache/waitlist/idx, exchanges data with protocol layer and object/delta modules.

**Protocol layer**: `protocol/*` - drives info-refs/upload-pack/receive-pack via pkt-line, uses app-provided `RepositoryAccess` and `AuthenticationService` traits.

**Object model**: `internal/object` - Blob/Tree/Commit/Tag/Note parsing/serialization with `ObjectTrait`.
**Object model**: `internal/object` - standard Git objects (Blob/Tree/Commit/Tag/Note) and AI objects, all implementing `ObjectTrait` for unified serialization.

**Delta/compression**: `delta/` and `zstdelta/` - delta encoding/decoding, zstd dictionary compression.

## AI Object Model

The AI object model lives in `src/internal/object/` alongside standard Git objects. All AI objects implement `ObjectTrait`, share a common `Header` (UUID v7, timestamps, creator `ActorRef`), and are serialized as JSON.

### End-to-End Flow

```
① User input
② Intent (Draft → Active → Completed)
③ Plan (steps + ContextPipeline)
④ Task (constraints + acceptance criteria)
⑤ Run (baseline commit + environment)
├── Provenance (LLM config, 1:1)
├── ContextSnapshot (static context, optional)
├── ⑥ ToolInvocation (action log, 1:N)
├── ⑦ PatchSet (candidate diff)
├── ⑧ Evidence (test/lint/build, 1:N)
⑨ Decision (commit / retry / abandon / rollback)
⑩ Intent (Completed, commit recorded)
```

### AI Object Files

| File | Object(s) | Role |
|------|-----------|------|
| `intent.rs` | `Intent`, `IntentStatus` | User prompt + AI interpretation; workflow entry/exit |
| `plan.rs` | `Plan`, `PlanStep`, `StepStatus` | Ordered steps from an Intent; revision chain via `previous` |
| `task.rs` | `Task`, `TaskStatus`, `GoalType` | Unit of work with constraints and acceptance criteria |
| `run.rs` | `Run`, `RunStatus`, `Environment` | Single execution attempt; accumulates artifacts |
| `tool.rs` | `ToolInvocation`, `IoFootprint` | Per-tool-call action log with file I/O tracking |
| `patchset.rs` | `PatchSet`, `PatchSetStatus` | Candidate unified diff with touched-file summary |
| `evidence.rs` | `Evidence`, `EvidenceKind` | Validation output (test, lint, build) |
| `decision.rs` | `Decision`, `Verdict` | Terminal verdict on a Run |
| `provenance.rs` | `Provenance`, `TokenUsage` | LLM model config and token metrics |
| `context.rs` | `ContextSnapshot`, `ContextItem` | Static file/URL/snippet capture at Run start |
| `pipeline.rs` | `ContextPipeline`, `ContextFrame` | Dynamic sliding-window context during planning |

### Shared Types (`types.rs`)

- `Header` — common header for all AI objects (UUID v7 `object_id`, `object_type`, `created_at`, `updated_at`, `created_by`)
- `ActorRef` — actor identity with kind (`agent`, `human`, `system`, `tool`) and name
- `ArtifactRef` — reference to an external artifact (kind + locator)
- `ObjectType` — enum covering both standard Git types and AI types
- `IntegrityHash` — SHA-256 content hash for commit references in AI objects (in `integrity.rs`)

### Key Patterns

- **Append-only history**: `Intent.statuses`, `PlanStep.statuses`, `Task.runs`, `Run.patchsets` — append-only vectors that preserve full history.
- **Snapshot references**: `Run.plan` records the Plan version at execution time and never changes; `Intent.plan` always points to the latest revision.
- **Revision chains**: `Plan.previous` links to the prior Plan version, forming an immutable chain.
- **Recursive decomposition**: `PlanStep.task` can reference a sub-Task with its own Run/Plan lifecycle; `Task.parent` provides the reverse link.
- **Context separation**: `ContextSnapshot` (static, at Run start) vs `ContextPipeline` (dynamic, accumulated during planning with frame eviction).
- **Serde conventions**: `#[serde(default)]` + `skip_serializing_if` on optional/empty fields; `rename_all = "snake_case"` on enums; `#[serde(alias = "...")]` for backward-compatible renames.

### Documentation

Full AI object lifecycle, field-level docs, and usage examples: `docs/ai.md`.

## Key Data Flows

**Pack Decode**: `Pack::decode(reader, callback)` or `Pack::decode_stream(stream, sender)` for async
Expand All @@ -59,14 +137,17 @@ hash.rs / utils.rs / errors.rs (shared infrastructure)
- upload-pack: parse want/have → `PackGenerator` builds pack stream
- receive-pack: parse commands → decode pack → store via `RepositoryAccess`

**AI Object Persistence**: AI objects are stored as content-addressed JSON blobs in the Git object database using their own `ObjectType` discriminator. They are excluded from pack encode/decode paths (rejected at the pack layer boundary).

## Coding Conventions

- **Language**: Rust Edition 2024, async/await with tokio, tracing for observability
- **Errors**: `thiserror` for library errors, `anyhow` for binaries/tests
- **Style**: rustfmt defaults, clippy warnings as errors for new code
- **Style**: rustfmt defaults (nightly), clippy warnings as errors for new code
- **Safety**: Avoid `unwrap()`/`expect()` in library code; return `Result<_, _>`
- **Performance**: Use iterators, streaming I/O, bounded allocations in hot paths
- **FFI/unsafe**: Only when required, with `// SAFETY:` comment and tests
- **AI objects**: JSON serialization via serde; `ObjectTrait` implementation with `from_bytes`/`to_data`/`get_type`/`get_size`; doc comments follow the pattern: module-level Position in Lifecycle diagram, Relationships table, Purpose section, field-level docs

## Hash Algorithm

Expand All @@ -77,6 +158,8 @@ use git_internal::hash::{set_hash_kind, HashKind};
set_hash_kind(HashKind::Sha1); // or HashKind::Sha256
```

AI objects use `IntegrityHash` (always SHA-256) for commit references, independent of the repository's hash algorithm.

## Concurrency Model

- **ThreadPool**: parallel inflate and delta rebuild during pack decode
Expand All @@ -87,13 +170,34 @@ set_hash_kind(HashKind::Sha1); // or HashKind::Sha256

## Key Types to Know

**Standard Git**:
- `Pack` - main pack decoder/encoder entry point
- `Entry` / `EntryMeta` - decoded object with metadata (offset, CRC, path)
- `ObjectHash` - SHA-1 or SHA-256 object identifier
- `ObjectType` - Blob/Tree/Commit/Tag enum
- `ObjectType` - Blob/Tree/Commit/Tag + AI type variants
- `RepositoryAccess` - trait for storage backend integration
- `GitProtocol` / `SmartProtocol` - protocol handling traits

**AI Objects**:
- `Intent` - workflow entry point; user prompt + AI interpretation
- `Plan` / `PlanStep` - planning artifact with ordered steps
- `Task` - stable work identity with acceptance criteria
- `Run` - execution attempt; records baseline commit and environment
- `PatchSet` - candidate diff artifact
- `Evidence` - validation result (test/lint/build)
- `Decision` - terminal verdict (Commit/Retry/Abandon/Rollback)
- `Provenance` - LLM configuration and token usage
- `ContextSnapshot` / `ContextPipeline` - static and dynamic context
- `ToolInvocation` - per-tool-call action log
- `Header` / `ActorRef` - shared metadata types

## Test Data

Real pack files in `tests/data/packs/` (e.g., `small-sha1.pack`). Use for decode/encode roundtrip testing.
Real pack files in `tests/data/packs/` (e.g., `small-sha1.pack`). Use for decode/encode roundtrip testing. AI object unit tests are inline in each module file.

## Documentation

- `docs/ARCHITECTURE.md` - overall library architecture
- `docs/GIT_OBJECTS.md` - standard Git object format reference
- `docs/GIT_PROTOCOL_GUIDE.md` - Git smart protocol guide
- `docs/ai.md` - AI object model: lifecycle, fields, and usage examples
14 changes: 11 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@
name = "git-internal"
version = "0.6.0"
edition = "2024"
authors = ["Eli Ma <genedna@gmail.com>"]
description = "High-performance Rust library for Git internal objects, Pack files, and AI-assisted development objects (Intent, Plan, Task, Run, Evidence, Decision) with delta compression, streaming I/O, and smart protocol support."
keywords = ["git", "pack", "delta", "ai-objects", "monorepo"]
categories = ["development-tools", "encoding", "parser-implementations"]
documentation = "https://libra.tools/docs/internal"
readme = "README.md"
homepage = "https://libra.tools"
repository = "https://github.com/web3infra-foundation/libra"
license = "MIT"
description = "Git-Internal is a high-performance Rust library for encoding and decoding Git internal objects and Pack files."
exclude = ["tests"]
exclude = ["tests", ".github"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[badges]
maintenance = { status = "actively-developed" }

[dependencies]
bstr = "1.12.1"
Expand Down
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Web3 Infrastructure Foundation

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Loading