Skip to content

chore: senior-dev polish pass on repo root#65

Merged
Gradata merged 1 commit into
mainfrom
chore/senior-dev-cleanup
Apr 15, 2026
Merged

chore: senior-dev polish pass on repo root#65
Gradata merged 1 commit into
mainfrom
chore/senior-dev-cleanup

Conversation

@Gradata

@Gradata Gradata commented Apr 15, 2026

Copy link
Copy Markdown
Owner

Clean up noob-flag signals in public repo root:

  • Drop sdk/ folder (contained only stale release docs; real code lives in src/gradata/). Unique PyPI trusted-publishing + release content ported to docs/contributing/pypi-setup.md.
  • Drop memory/project_s102_handoff.md (internal session handoff leaked into public repo). Added memory/ to .gitignore for defense.
  • Drop .gitnexusignore (niche tool config). Patterns already covered by .gitignore except *.sqlite and *.jsonl, which are now added there.
  • Add 'Repo layout' section to README.md so newcomers parse the top-level directories in 30 seconds.
  • Flesh out examples/: add with_openai.py (real wrap_openai middleware usage) and with_claude_code.py (mirrors what the installed /plugin install gradata hooks do, via the same Brain.correct + Brain.apply_brain_rules API).

Behavior-neutral: 2257 passed, 23 skipped (pytest tests/ -x -q). No src/ changes.

…re cleanup + README layout section)

Signed-off-by: Oliver Le <oliver@gradata.ai>

@greptile-apps greptile-apps 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.

Gradata has reached the 50-review limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown
📝 Walkthrough
  • Removed sdk/ folder containing outdated release documentation (PYPI-SETUP.md, RELEASE.md, mkdocs.yml); PyPI publishing information relocated to docs/contributing/pypi-setup.md
  • Deleted memory/project_s102_handoff.md internal session handoff file and added memory/ directory to .gitignore
  • Removed .gitnexusignore file; redundant exclusion patterns added to .gitignore (including *.sqlite and *.jsonl)
  • Added "Repo layout" section to README.md documenting purpose of top-level directories for new users
  • Added docs/contributing/pypi-setup.md comprehensive guide for Gradata PyPI/TestPyPI releases using Trusted Publishing workflow
  • Enhanced examples/ directory with two new demonstration scripts:
    • with_openai.py: shows raw OpenAI SDK integration via wrap_openai middleware
    • with_claude_code.py: demonstrates Brain.correct() and Brain.apply_brain_rules() API usage
  • Updated examples/README.md with quality constraints and documentation for new examples

No breaking changes, security fixes, or new public API methods.

Walkthrough

This PR reorganizes and consolidates repository documentation: moves PyPI release documentation from sdk/ subdirectory to docs/contributing/, removes internal project handoff notes and .gitnexusignore configuration, updates .gitignore to exclude session memory and data files, adds example scripts demonstrating Gradata integration with OpenAI and Claude Code, and documents repository structure in the main README.

Changes

Cohort / File(s) Summary
Ignore and Config
.gitignore, .gitnexusignore
Updated .gitignore to exclude *.sqlite, *.jsonl files and memory/ directory; removed .gitnexusignore file entirely.
Documentation Consolidation
docs/contributing/pypi-setup.md
New centralized PyPI release documentation covering Trusted Publishing setup, version conventions, tag-based release workflow, and troubleshooting scenarios.
Removed SDK Documentation
sdk/PYPI-SETUP.md, sdk/RELEASE.md, sdk/mkdocs.yml
Removed PyPI setup, release process documentation, and MkDocs configuration from SDK directory (functionality consolidated to docs/contributing/).
Root Documentation Updates
README.md
Added "Repo layout" section describing purpose of key top-level directories and files.
Examples Updates
examples/README.md, examples/with_openai.py, examples/with_claude_code.py
Updated examples README with quality constraints and new example references; added two new runnable example scripts demonstrating Gradata integration with OpenAI SDK and Claude Code plugin workflows.
Internal Cleanup
memory/project_s102_handoff.md
Removed internal project handoff document with session notes and work tracking.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Suggested labels

security, docs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change—a cleanup polish pass on the repository root—and accurately reflects the primary focus of the changeset.
Description check ✅ Passed The description is directly related to the changeset, detailing each removal and addition with context, and confirms no production code was affected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/senior-dev-cleanup

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

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying gradata-dashboard with  Cloudflare Pages  Cloudflare Pages

Latest commit: 23732b5
Status: ✅  Deploy successful!
Preview URL: https://44f39df1.gradata-dashboard.pages.dev
Branch Preview URL: https://chore-senior-dev-cleanup.gradata-dashboard.pages.dev

View logs

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
.gitignore (1)

1-186: 🧹 Nitpick | 🔵 Trivial

Consider deduplicating patterns across sections.

The .gitignore file contains numerous duplicate patterns scattered across different sections:

  • system.db (lines 29, 103)
  • brain.manifest.json (lines 28, 104)
  • .vectorstore/ (lines 27, 100)
  • __pycache__/ and *.pyc (lines 33-34, 95-96)
  • .env and .env.* (lines 5, 7, 138-139, 181-183)
  • node_modules/ (lines 2, 152)
  • .vscode/ (lines 53, 149)
  • .claude/ (lines 50, 132)
  • CLAUDE.md (lines 47, 128)

While duplicates don't break functionality, consolidating them would improve maintainability and reduce confusion when updating ignore rules.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.gitignore around lines 1 - 186, Consolidate duplicate ignore patterns by
removing repeated entries and keeping a single canonical entry for each pattern
(e.g., system.db, brain.manifest.json, .vectorstore/, __pycache__/, *.pyc, .env,
.env.*, node_modules/, .vscode/, .claude/, CLAUDE.md) — locate these symbols
across the file and merge them into the most appropriate section (for example:
Environment and credentials for .env*, Cache/Auto-generated for .vectorstore/
and __pycache__, Dependencies for node_modules/) so each pattern appears only
once and related rules are grouped for maintainability.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@examples/with_openai.py`:
- Around line 18-22: The current manual creation of brain_dir and lessons.md
fails because Brain's constructor expects the full initialized layout; replace
the mkdir/touch pattern with the SDK initializer by calling Brain.init(...) to
create system.db, brain.manifest.json, and .embed-manifest.json before
instantiating Brain (remove brain_dir.mkdir(...) and (brain_dir /
"lessons.md").touch() and invoke Brain.init with the same path, then construct
Brain(str(brain_dir)) or use the initializer's returned instance if it returns
one).

---

Outside diff comments:
In @.gitignore:
- Around line 1-186: Consolidate duplicate ignore patterns by removing repeated
entries and keeping a single canonical entry for each pattern (e.g., system.db,
brain.manifest.json, .vectorstore/, __pycache__/, *.pyc, .env, .env.*,
node_modules/, .vscode/, .claude/, CLAUDE.md) — locate these symbols across the
file and merge them into the most appropriate section (for example: Environment
and credentials for .env*, Cache/Auto-generated for .vectorstore/ and
__pycache__, Dependencies for node_modules/) so each pattern appears only once
and related rules are grouped for maintainability.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b9532bbe-22bb-4641-a24e-b06ba4ac1e30

📥 Commits

Reviewing files that changed from the base of the PR and between 5fd7215 and 23732b5.

📒 Files selected for processing (11)
  • .gitignore
  • .gitnexusignore
  • README.md
  • docs/contributing/pypi-setup.md
  • examples/README.md
  • examples/with_claude_code.py
  • examples/with_openai.py
  • memory/project_s102_handoff.md
  • sdk/PYPI-SETUP.md
  • sdk/RELEASE.md
  • sdk/mkdocs.yml
💤 Files with no reviewable changes (5)
  • .gitnexusignore
  • sdk/mkdocs.yml
  • memory/project_s102_handoff.md
  • sdk/PYPI-SETUP.md
  • sdk/RELEASE.md
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test (3.13)
  • GitHub Check: Cloudflare Pages
🧰 Additional context used
🪛 LanguageTool
docs/contributing/pypi-setup.md

[uncategorized] ~3-~3: The official name of this software platform is spelled with a capital “H”.
Context: ...ta package on PyPI is published by the [sdk-publish.yml`](../../.github/workflows/sdk-publish.yml) GitHub Actio...

(GITHUB)


[uncategorized] ~148-~148: The official name of this software platform is spelled with a capital “H”.
Context: ...tests/**, or pyproject.toml triggers [sdk-test.yml`](../../.github/workflows/sdk-test.yml) on Python 3.11,...

(GITHUB)

🔇 Additional comments (6)
.gitignore (2)

31-32: LGTM! Appropriate patterns for auto-generated files.

The addition of *.sqlite and *.jsonl patterns aligns with the PR objective of migrating relevant exclusions from the removed .gitnexusignore file. These patterns are correctly placed in the "Auto-generated" section.


37-38: LGTM! Clear documentation of sensitive directory exclusion.

The memory/ exclusion with its explanatory comment effectively prevents internal session handoff leaks, addressing the security concern mentioned in the PR objectives.

examples/with_claude_code.py (1)

22-25: Same brain-initialization risk as examples/with_openai.py.

This uses the same uninitialized-directory pattern. Please apply the same fix (Brain.init(...)) here as well.

README.md (1)

30-40: Repo layout section is clear and useful.

Nice addition—this improves onboarding and helps contributors quickly orient themselves in the repository.

docs/contributing/pypi-setup.md (1)

1-150: Release documentation aligns with workflow behavior.

This is a solid consolidation: tag strategy, Trusted Publishing setup, rollback handling, and operational checks are all clearly documented.

examples/README.md (1)

3-36: Examples index update looks good.

The new entries and run commands improve discoverability and make the examples folder much easier to use.

Comment thread examples/with_openai.py
Comment on lines +18 to +22
brain_dir = Path("./demo-brain")
brain_dir.mkdir(exist_ok=True)
(brain_dir / "lessons.md").touch()
brain = Brain(str(brain_dir))

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify Brain initialization contract and initializer availability.
set -euo pipefail

echo "== Brain constructor checks =="
rg -n -C3 'class Brain|def __init__\(|BrainNotFoundError|not initialized|lessons\.md|system\.db' src/gradata/brain.py

echo
echo "== Brain initializer presence =="
rg -n -C3 'def init\(' src/gradata/brain.py

Repository: Gradata/gradata

Length of output: 3254


🏁 Script executed:

#!/bin/bash
# Get the complete Brain.init() method implementation
rg -n -A 30 '@classmethod' src/gradata/brain.py | grep -A 30 'def init'

Repository: Gradata/gradata

Length of output: 1348


🏁 Script executed:

#!/bin/bash
# Get full Brain.init() implementation
rg -n -A 50 'def init\(' src/gradata/brain.py | head -60

echo
echo "== Check onboard function =="
rg -n -C 5 'def onboard' src/gradata/onboard.py | head -50

Repository: Gradata/gradata

Length of output: 2357


🏁 Script executed:

#!/bin/bash
# Get full onboard() implementation
rg -n -A 80 'def onboard\(' src/gradata/onboard.py

Repository: Gradata/gradata

Length of output: 3446


🏁 Script executed:

#!/bin/bash
# Search for where manifest.json and system.db are created/written in onboard
rg -n 'brain\.manifest\.json|system\.db|write_text|mkdir|\.db|manifest' src/gradata/onboard.py | head -40

Repository: Gradata/gradata

Length of output: 1252


🏁 Script executed:

#!/bin/bash
# Verify the example file content around lines 18-22
sed -n '10,30p' examples/with_openai.py

Repository: Gradata/gradata

Length of output: 688


Replace manual initialization with Brain.init().

Line 21 will fail at runtime. Creating the directory and touching lessons.md does not initialize the required files (system.db, brain.manifest.json, .embed-manifest.json). The Brain constructor will fail when attempting to access these files. Use the SDK initializer instead:

Proposed fix
 brain_dir = Path("./demo-brain")
-brain_dir.mkdir(exist_ok=True)
-(brain_dir / "lessons.md").touch()
-brain = Brain(str(brain_dir))
+brain = Brain.init(str(brain_dir))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/with_openai.py` around lines 18 - 22, The current manual creation of
brain_dir and lessons.md fails because Brain's constructor expects the full
initialized layout; replace the mkdir/touch pattern with the SDK initializer by
calling Brain.init(...) to create system.db, brain.manifest.json, and
.embed-manifest.json before instantiating Brain (remove brain_dir.mkdir(...) and
(brain_dir / "lessons.md").touch() and invoke Brain.init with the same path,
then construct Brain(str(brain_dir)) or use the initializer's returned instance
if it returns one).

@Gradata Gradata merged commit dabf954 into main Apr 15, 2026
6 checks passed
@Gradata Gradata deleted the chore/senior-dev-cleanup branch April 15, 2026 13:29
Gradata added a commit that referenced this pull request Apr 15, 2026
(c) Wire dormant emitter
------------------------
SessionHistory in integrations/session_history.py subscribes to
`rules.injected` but nothing in the codebase ever emits it — grep of
the whole tree shows only the subscriber. That leaves its per-session
rule effectiveness tracking (compute_effectiveness / on_session_ended)
silently dead.

brain.apply_brain_rules() now fires the event on the in-memory bus
after format_rules_for_prompt(applied). Cache hits skip the emit
intentionally: SessionHistory dedups via a set, the cache is per
scope, and every fresh scope hits the compute path.

The other two events SessionHistory subscribes to (correction.created,
session.ended) already have emitters — checked at _core.py:138, 574,
854. So this is the one missing wire.

Regression test: test_apply_brain_rules_emits_rules_injected — seeds
a graduated TONE rule through a real correct() loop, subscribes a
SessionHistory to the brain's bus, calls apply_brain_rules, asserts
the injected set is populated.

(b) Gitignore on-disk orphans
-----------------------------
Three untracked leftovers from the S105 repo splits keep showing up
in `git status` and sometimes get accidentally re-added:

  - /cloud/           moved to private Gradata/gradata-cloud (#76)
  - /sdk/             superseded by the flattened layout (#65)
  - /railway.toml     now lives in gradata-cloud/cloud/railway.toml

Also added apollo-leads-*.csv since sales exports have leaked into
the repo root before and belong in brain/leads/, not the SDK tree.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Gradata added a commit that referenced this pull request Apr 15, 2026
(c) Wire dormant emitter
------------------------
SessionHistory in integrations/session_history.py subscribes to
`rules.injected` but nothing in the codebase ever emits it — grep of
the whole tree shows only the subscriber. That leaves its per-session
rule effectiveness tracking (compute_effectiveness / on_session_ended)
silently dead.

brain.apply_brain_rules() now fires the event on the in-memory bus
after format_rules_for_prompt(applied). Cache hits skip the emit
intentionally: SessionHistory dedups via a set, the cache is per
scope, and every fresh scope hits the compute path.

The other two events SessionHistory subscribes to (correction.created,
session.ended) already have emitters — checked at _core.py:138, 574,
854. So this is the one missing wire.

Regression test: test_apply_brain_rules_emits_rules_injected — seeds
a graduated TONE rule through a real correct() loop, subscribes a
SessionHistory to the brain's bus, calls apply_brain_rules, asserts
the injected set is populated.

(b) Gitignore on-disk orphans
-----------------------------
Three untracked leftovers from the S105 repo splits keep showing up
in `git status` and sometimes get accidentally re-added:

  - /cloud/           moved to private Gradata/gradata-cloud (#76)
  - /sdk/             superseded by the flattened layout (#65)
  - /railway.toml     now lives in gradata-cloud/cloud/railway.toml

Also added apollo-leads-*.csv since sales exports have leaked into
the repo root before and belong in brain/leads/, not the SDK tree.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant