Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
57 changes: 57 additions & 0 deletions .github/workflows/no-ai-trailers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: no-ai-trailers

on:
pull_request:
branches: [dev, main]

permissions:
contents: read

jobs:
scan:
name: scan PR commits for AI provenance leaks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Reject AI-tooling tells in commit messages
env:
BASE: ${{ github.event.pull_request.base.sha }}
HEAD: ${{ github.event.pull_request.head.sha }}
run: |
set -eu

patterns=(
'Co-Authored-By: Claude'
'co-authored-by: claude'
'claude\.ai/code/session_'
'noreply@anthropic\.com'
'Generated with \[Claude Code\]'
'🤖 Generated with'
)

range="$BASE..$HEAD"
violators=$(
git log --format='%H%n%B%n--END--' "$range" \
| awk -v RS='--END--\n' 'NF { print $0 }'
)
Comment thread
joshuaboys marked this conversation as resolved.
Outdated

fail=0
while IFS= read -r sha; do
[ -z "$sha" ] && continue
body=$(git log -1 --format='%B' "$sha")
for p in "${patterns[@]}"; do
if printf '%s' "$body" | grep -qE "$p"; then
echo "::error::commit $sha leaks AI provenance — matches: $p"
Comment thread
joshuaboys marked this conversation as resolved.
fail=1
fi
done
done < <(git log --format='%H' "$range")

if [ "$fail" -ne 0 ]; then
echo "::error::Reword the offending commits before merging."
exit 1
fi
echo "no AI provenance leaks found in $(git rev-list --count "$range") commits"
37 changes: 37 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
# Block commit messages that leak AI-tooling provenance.
#
# Rejects:
# - "Co-Authored-By: Claude*" (Claude Code's default trailer)
# - claude.ai/code/session_* URLs (Claude Code session links)
# - [email protected] authorship references
# - "Generated with Claude Code" / "🤖 Generated with" footers
#
# Override: COMMIT_ALLOW_AI_TRAILERS=1 git commit ... (use only when intentional).

set -eu

msg_file="$1"

if [ "${COMMIT_ALLOW_AI_TRAILERS:-0}" = "1" ]; then
exit 0
fi

# Strip standard comment lines so we only inspect actual message content.
content=$(grep -v '^#' "$msg_file" || true)

found=""
case "$content" in
*"Co-Authored-By: Claude"*) found="Co-Authored-By: Claude trailer" ;;
*"co-authored-by: claude"*) found="co-authored-by: claude trailer" ;;
*"claude.ai/code/session_"*) found="claude.ai/code/session_* URL" ;;
*"[email protected]"*) found="[email protected] reference" ;;
*"Generated with [Claude Code]"*) found="Generated with [Claude Code] footer" ;;
*"🤖 Generated with"*) found="🤖 Generated with footer" ;;
Comment thread
joshuaboys marked this conversation as resolved.
Outdated
esac

if [ -n "$found" ]; then
echo "✖ commit-msg blocked: message contains $found." >&2
echo " Remove the line, or set COMMIT_ALLOW_AI_TRAILERS=1 if this is intentional." >&2
exit 1
fi
8 changes: 8 additions & 0 deletions .mailmap
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# .mailmap — display-name normalisation for git log / GitHub.
#
# Maps inconsistent author names to a canonical display name without
# rewriting history. Format: <canonical name> <commit email> <commit name> <commit email>.
Comment thread
joshuaboys marked this conversation as resolved.
Outdated
# See `git help mailmap`.

Josh Boys <[email protected]> aneki <[email protected]>
Josh Boys <[email protected]> aneki <[email protected]>
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- GitHub sync commands for Claude Code Web integration
- Automatic secret detection and redaction
- Export/import functionality for data portability
- Comprehensive test coverage across all packages
- Test coverage across all packages

### Security

Expand Down
58 changes: 12 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,18 @@ Or capture manually with the CLI (`kindling log`, `kindling capsule open/close`)

## Packages

| Package | Description |
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------- |
| [`@eddacraft/kindling`](./packages/kindling) | **Main package**: core + SQLite store + provider + API server |
| [`@eddacraft/kindling-cli`](./packages/kindling-cli) | CLI for reading, writing, and managing memory |
| [`@eddacraft/kindling-core`](./packages/kindling-core) | Lightweight types + KindlingService (for adapter authors) |
| [`@eddacraft/kindling-store-sqljs`](./packages/kindling-store-sqljs) | sql.js WASM store (browser environments) |
| [`@eddacraft/kindling-adapter-claude-code`](./packages/kindling-adapter-claude-code) | Claude Code hooks integration |
| [`@eddacraft/kindling-adapter-opencode`](./packages/kindling-adapter-opencode) | OpenCode session integration |
| [`@eddacraft/kindling-adapter-pocketflow`](./packages/kindling-adapter-pocketflow) | PocketFlow workflow integration |
| Package | Description |
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| [`@eddacraft/kindling`](./packages/kindling) | **Main package**: re-exports core + SQLite store + local FTS provider |
| [`@eddacraft/kindling-core`](./packages/kindling-core) | Domain types, KindlingService, validation (for adapter authors, browser) |
| [`@eddacraft/kindling-store-sqlite`](./packages/kindling-store-sqlite) | SQLite persistence with FTS5 and WAL mode |
| [`@eddacraft/kindling-store-sqljs`](./packages/kindling-store-sqljs) | sql.js WASM store for browser compatibility |
| [`@eddacraft/kindling-provider-local`](./packages/kindling-provider-local) | Local FTS-based retrieval provider with deterministic ranking |
| [`@eddacraft/kindling-server`](./packages/kindling-server) | HTTP API server for multi-agent concurrency (Fastify) |
| [`@eddacraft/kindling-cli`](./packages/kindling-cli) | CLI tools for inspection, search, and management |
| [`@eddacraft/kindling-adapter-opencode`](./packages/kindling-adapter-opencode) | OpenCode session integration |
| [`@eddacraft/kindling-adapter-pocketflow`](./packages/kindling-adapter-pocketflow) | PocketFlow workflow integration with intent and confidence tracking |
| [`@eddacraft/kindling-adapter-claude-code`](./packages/kindling-adapter-claude-code) | Claude Code hooks integration |

## Programmatic Usage

Expand Down Expand Up @@ -213,21 +216,6 @@ service.closeCapsule(capsule.id, {
db.close();
```

## Packages

| Package | Description |
| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| [`@eddacraft/kindling`](./packages/kindling) | **Main package**: re-exports core + SQLite store + local FTS provider |
| [`@eddacraft/kindling-core`](./packages/kindling-core) | Domain types, KindlingService, validation (for adapter authors, browser) |
| [`@eddacraft/kindling-store-sqlite`](./packages/kindling-store-sqlite) | SQLite persistence with FTS5 and WAL mode |
| [`@eddacraft/kindling-store-sqljs`](./packages/kindling-store-sqljs) | sql.js WASM store for browser compatibility |
| [`@eddacraft/kindling-provider-local`](./packages/kindling-provider-local) | Local FTS-based retrieval provider with deterministic ranking |
| [`@eddacraft/kindling-server`](./packages/kindling-server) | HTTP API server for multi-agent concurrency (Fastify) |
| [`@eddacraft/kindling-cli`](./packages/kindling-cli) | CLI tools for inspection, search, and management |
| [`@eddacraft/kindling-adapter-opencode`](./packages/kindling-adapter-opencode) | OpenCode session integration |
| [`@eddacraft/kindling-adapter-pocketflow`](./packages/kindling-adapter-pocketflow) | PocketFlow workflow integration with intent and confidence tracking |
| [`@eddacraft/kindling-adapter-claude-code`](./packages/kindling-adapter-claude-code) | Claude Code hooks integration |

## Architecture

```diagram
Expand Down Expand Up @@ -261,28 +249,6 @@ db.close();
└──────────────────────────────┘
```

## CLI Usage

```bash
# Show database status
kindling status

# Search for context
kindling search "authentication error"
kindling search --session session-123

# List entities
kindling list capsules
kindling list pins
kindling list observations

# Pin important findings
kindling pin observation obs_abc123 --note "Root cause identified"

# Remove a pin
kindling unpin pin_xyz789
```

## Core Concepts

### Observations
Expand Down
8 changes: 4 additions & 4 deletions packages/kindling/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ Local memory and continuity engine for AI-assisted development.

**Kindling** captures observations (tool calls, diffs, commands, errors) from AI workflows, organizes them into capsules, and makes context retrievable with deterministic, explainable results. All data is stored locally using embedded SQLite with FTS5.

**Kindling** captures what happened.
**Anvil** enforces what should happen.
Request access to the Anvil closed beta → [eddacraft.ai](https://eddacraft.ai)

## Installation

```bash
Expand Down Expand Up @@ -129,3 +125,7 @@ Full documentation at [docs.eddacraft.ai/docs/kindling](https://docs.eddacraft.a
## License

Apache-2.0

## Related

- [Anvil](https://eddacraft.ai) — policy and enforcement layer for AI-assisted development; complements Kindling by enforcing what should happen rather than capturing what did.
Loading
Loading