3R Programs

AI · Systems · Portfolio Projects

Shared engine in progress

Nonprofit Grant Search Engine

An in-progress shared engine for nonprofit grant discovery, with ParaCliffHangers and the New York City Climbing Collective as named implementations. The technical goal is reusable search logic with controls that keep each nonprofit's data, credentials, prompts, Sheets, decisions, feedback, and logs separate.

What It Does

A shared grant-search engine with nonprofit-specific boundaries.

The project uses AI where it helps: finding and summarizing possible opportunities. The rest of the system is deliberately ordinary software: configuration, scheduling, deduplication, validation, Sheets writes, and logs.

One useful workflow

Both tools search for grant opportunities, deduplicate results, write new rows to the Google Sheet the team already uses, and read human feedback before the next run.

Two named implementations

ParaCliffHangers is grounded in adaptive climbing and disability-led outdoor recreation. NY3C is grounded in climbing equity, youth development, gear access, and NYC-metro funders.

Shared engine, isolated context

The technical direction is a shared grant-search engine with organization-specific profiles, prompts, credentials, Sheets, feedback, run history, and logs kept separate.

Workflow

The engine is shared. The nonprofit context is not.

This is the key safety and product lesson. Reuse should reduce maintenance cost without creating a path for one organization's search profile or decisions to leak into another's.

1

Configure the nonprofit profile

Each nonprofit has its own mission profile, program list, geography, preferred funder language, named-funder list, and negative filters. PCH and NY3C are named because the context matters.

2

Run the shared search engine

The engine uses the same repeatable mechanics: scheduled Python, Claude CLI, Google Sheets integration, deduplication, and output validation.

3

Keep search context organization-specific

The prompt context for one nonprofit does not include another nonprofit's profile, feedback, Sheet contents, or decisions. Reuse belongs in the engine, not in the organization's data.

4

Write to the right Sheet

New grant rows land in the Sheet assigned to that nonprofit. The team reviews them in familiar columns such as Decision and Notes instead of learning a new app.

5

Use feedback as calibration

Apply, Pass, Researching, and free-text notes become search feedback for that nonprofit only. This is the practical loop that makes the tool better without taking the decision away from the team.

6

Log enough to inspect later

Runs, prompts, output validation, duplicate decisions, errors, and write results should be recoverable so the engine is maintainable and explainable.

Controls

Everything that makes the shared engine safe has to be explicit.

The control model is part of the product, not an implementation footnote: separate credentials, separate Sheets, separate prompts, scoped feedback, scoped logs, and no cross-organization prompt context.

Credential and Sheet isolation

Each nonprofit should have separate service-account access, Sheet identifiers, environment values, and write targets. A PCH run should not be able to write to NY3C's Sheet.

No cross-organization prompt context

Profiles, keywords, feedback, decisions, notes, and prior results stay scoped to the active nonprofit. The model gets only the context needed for that organization's search.

Least-privilege operating model

The engine should use narrow permissions, separate configs, scoped logs, duplicate checks by organization, and validation before writing anything the team will review.

Technology

The stack tells the product story.

These pages are not replacing the private repositories. They summarize what a reviewer would see there: the architecture choices, evidence surfaces, tests, and boundaries behind the build.

Current implementations

  • Python 3.12 grant-search agents
  • Claude Code CLI through `claude --print`
  • Google Sheets API v4 with service-account authentication
  • macOS launchd for scheduled execution
  • pytest and ruff for local verification

Shared-engine direction

  • One reusable search runner
  • Organization-specific config files or profiles
  • Separate credentials and Sheet targets
  • Per-organization prompt context and keyword strategy
  • Per-organization feedback, decision history, and run logs

Safety controls

  • No cross-organization prompt context
  • No shared Sheet writes
  • No shared service-account scope unless explicitly safe
  • Deduplication scoped to the active nonprofit
  • Output validation before any Sheet append

Why this shows technical judgment

  • Shared code reduces maintenance cost
  • Separate configuration prevents data leakage
  • Sheets keep adoption friction low
  • AI is used for search and fit reasoning, while Python handles repeatable mechanics

Repository Signals

What the repository contains.

For now, the repositories stay private while the public site explains the work. These notes summarize the files, routes, docs, checks, and review artifacts without exposing private configuration, credentials, or organization-specific data.

The two repos show the same workflow pattern applied to two different nonprofit missions. That makes the next step obvious: extract the repeatable engine and keep organization-specific context isolated.
The technical story is not just that AI can search. It is that the system can reuse code without reusing private nonprofit data, prompts, decisions, credentials, or logs.
The PCH history also shows a product judgment pivot: the earlier full-stack app proved technical range, but the simpler Sheet-based tool better matched nonprofit maintenance reality.
The future public version should expose the engine and sample configs while scrubbing real Sheet IDs, service-account details, nonprofit feedback, and any private operating data.