An independent, working prototype and architecture proposal for Zcash Community Grants (ZCG) decision support.
The prototype mirrors existing public records, preserves their provenance, reconciles them into canonical applications and funded-status grant records, and provides public review and authenticated operational views without asking ZCG to replace its current tools first.
Status: This is an independent prototype and architecture proposal, not an official ZCG production system unless relevant Zcash ecosystem stakeholders adopt it.
| Area | Current state |
|---|---|
| Source mirroring | GitHub issues and comments, two public ZCG Google Sheet tabs, linked Zcash Community Forum topics, and the Forum's Community Grants Updates category |
| Source refresh | Signed GitHub and Discourse callbacks feed a buffered, deduplicated targeted-refresh queue; a lightweight public-Sheet checksum check runs every 15 minutes; the existing Admin action and daily full refresh remain the verification and recovery path |
| Evidence preservation | Current source projections plus append-only, versioned source observations in PostgreSQL and optional aggregate JSON snapshots in private S3 |
| Reconciliation | Canonical applications, funded-status grant records, normalized FPF milestone/disbursement ledger rows, stale-grant cleanup when an application leaves a funded status, GitHub label normalization, source links, confidence scores, generated issues, and durable reviewer decisions |
| Decision history | Meeting-minute topics parsed into decision sources and grant mentions with rationale, speaker notes, provenance, and review status |
| Knowledge retrieval | PostgreSQL full-text search, pgvector embeddings, hybrid retrieval, citation-grounded answers, and application-scoped evidence packs |
| Committee decision support | Versioned, publicly viewable shared briefings plus temporary, private, or shared custom analyses with durable citation snapshots, freshness checks, and audit history |
| Product surfaces | Public review worklist, collapsible application registry, grant details, dedicated briefing pages, knowledge search, protected telemetry and reconciliation workspaces, and user access management |
| Access and audit | Better Auth sign-in emails containing both a secure link and one-time code, application-owned roles and permissions, server-side authorization, and audit events |
| Deployment | Next.js on AWS Amplify SSR, Aurora PostgreSQL through the RDS Data API, and CDK-managed workers, snapshots, secrets, logs, and optional alarms |
Milestones and explicitly recorded disbursements from the mirrored FPF Sheet are now normalized as read-only, provenance-linked ledger evidence. They do not by themselves prove that a progress update was accepted, a payment request was approved, or a transaction settled on-chain. Progress updates, payment requests/approvals, RFPs, KYC, agreements, attachments, an applicant portal, and controlled writeback are not yet implemented as first-class workflows.
These are reconciliation outputs, not authoritative ZCG production totals. They were observed on the live prototype on July 14, 2026 after the latest grant reconciliation completed. The deployed refresh design combines targeted GitHub and Forum callbacks, 15-minute Google Sheet change checks, a daily full verification, and an Administrator-started full refresh.
| Metric | Count |
|---|---|
| Mirrored source records | 4,391 |
| Canonical applications | 632 |
| Funded-status grant records | 161 |
| Open reconciliation items | 12 |
| Open warning or error items | 1 |
| Grant knowledge documents | 15,924 |
| Embedded knowledge documents | 15,871 |
The funded-status total counts canonical grant records whose applications are
approved, active, or completed; declined and cancelled applications are
excluded. For context, the July 13
OpenZcash payment-ledger snapshot contains
170 regular ZCG project names and 6 coinholder projects (176 combined). That
broader historical ledger includes cancelled or vetoed entries and title
aliases, so it is not a like-for-like grant total. The interface exposes this
distinction from an information control beside each funded-grant statistic.
ZCG currently works across public routing, application intake, community discussion, financial tracking, and private/manual operations. No single tool owns the full grant lifecycle.
The diagram is based on public-system discovery performed on June 28, 2026. The private/manual steps need validation with ZCG and Financial Privacy Foundation (FPF) system owners. The editable Figma source and detailed discovery notes record the evidence and open questions.
The documented public workflow is broadly:
- The ZCG website routes an applicant to the GitHub grant issue form.
- The applicant cross-posts the application to the Zcash Community Forum.
- FPF performs eligibility review and coordinates revisions.
- The community reviews the application publicly before ZCG decides.
- FPF coordinates applicant notification, KYC, and the grant agreement.
- Forum updates gate milestone payouts, while payment and portfolio summaries are maintained in the ZCG Google Sheet.
In parallel, GitHub labels and comments, Forum discussions, the Google Sheet, Jotform RFP intake, meeting minutes, and private operational records each hold part of the state. People are the integration layer that keeps those records aligned.
The current prototype is deliberately read-only at the source boundary. It mirrors public evidence, reconciles related records, and only then publishes canonical and search-oriented views.
flowchart LR
subgraph currentSources ["Currently ingested"]
github["GitHub issues and comments"]
sheet["Two Google Sheet tabs"]
linkedForum["Linked Forum topics"]
forumUpdates["Forum updates category"]
end
notConnected["Website, Jotform, private operations"]
syncWorker["Sync worker"]
reconcile["Grant reconciliation"]
minuteParser["Meeting-minute parser"]
knowledgeIndex["Knowledge indexing"]
reviewer["Reviewer decisions"]
subgraph evidenceStore ["Evidence storage"]
snapshots[("S3 snapshots and source_snapshots")]
sourceRecords[("source_records")]
sourceObservations[("source_record_observations")]
runRecords[("sync_runs and audit_events")]
end
subgraph canonicalStore ["Canonical and review storage"]
applications[("grant_applications and grants")]
milestoneLedger[("grant_milestones and grant_disbursements")]
applicationLabels[("grant_application_github_labels")]
sourceLinks[("source_links")]
reconciliationIssues[("reconciliation_issues")]
manualDecisions[("reconciliation decisions")]
decisionHistory[("decision sources and mentions")]
end
subgraph retrievalStore ["Retrieval storage"]
knowledgeDocs[("grant_knowledge_documents")]
knowledgeActivity[("queries and answer jobs")]
analysisReports[("analysis reports and evidence snapshots")]
end
github --> syncWorker
sheet --> syncWorker
github -->|"Discovers URLs"| linkedForum
sheet -->|"Discovers URLs"| linkedForum
linkedForum --> syncWorker
forumUpdates --> syncWorker
notConnected -.->|"No connector"| syncWorker
syncWorker --> snapshots
syncWorker --> sourceRecords
sourceRecords --> sourceObservations
syncWorker --> runRecords
sourceRecords --> reconcile
sourceRecords --> minuteParser
reviewer --> manualDecisions
manualDecisions --> reconcile
reconcile --> applications
reconcile --> milestoneLedger
reconcile --> applicationLabels
reconcile --> sourceLinks
reconcile --> reconciliationIssues
reconcile --> minuteParser
minuteParser --> decisionHistory
minuteParser --> sourceLinks
minuteParser --> reconciliationIssues
applications --> knowledgeIndex
applicationLabels --> knowledgeIndex
sourceLinks --> knowledgeIndex
decisionHistory --> knowledgeIndex
reconciliationIssues --> knowledgeIndex
knowledgeIndex --> knowledgeDocs
knowledgeDocs --> knowledgeActivity
knowledgeDocs --> analysisReports
knowledgeActivity --> analysisReports
The dotted line means there is no implemented connector for the website, Jotform, or private FPF/ZCG operations. They are shown so the absence is explicit rather than silently treated as complete coverage.
| Source or input | Mirrored storage | Canonical or derived storage |
|---|---|---|
| GitHub issues | source_records as github_issue |
grant_applications; normalized grant_application_github_labels; source_links; possible grants and reconciliation_issues |
| GitHub comments | source_records as github_issue_comment |
Parent-application evidence; discovered Forum URLs can produce linked Forum records |
| ZCG Google Sheet | google_sheet_tab and google_sheet_row current records plus append-only source_record_observations; All Grants rows use normalized Grant Platform Link identities while row numbers remain locators |
Historical applications, funded-status grants, conservatively matched grant_milestones and grant_disbursements, source links, and reconciliation issues |
| Forum topics discovered in GitHub or Sheet data | source_records as forum_link, including topic metadata, posts, plain text, and rendered post HTML |
Primary-thread or supporting-reference source_links; knowledge documents |
| Forum Community Grants Updates category | forum_meeting_minutes or forum_update_topic source records |
Meeting minutes become grant_decision_sources, grant_decision_mentions, decision links, and review issues; generic update topics currently remain raw evidence |
| Reviewer judgments | Reconciliation UI/API or portable JSON import into reconciliation_decisions |
Link/unlink decisions, application relationships, and issue resolutions are replayed after generated reconciliation; field-override decisions are persisted but not yet applied |
| Canonical, linked-source, accepted decision, and open reconciliation evidence | Derived from the rows above | grant_knowledge_documents with full-text vectors and optional embeddings; grant_knowledge_queries and grant_knowledge_answer_jobs; versioned grant_analysis_reports with exact grant_analysis_report_evidence snapshots |
| Website, Jotform, KYC/agreement files, and payment/custody systems | Not ingested | No current tables or connectors |
Meeting-minute parsing retains list ancestry from the mirrored HTML so supporting links stay within the application discussion. Decision-reference labels and RFP publication notices do not create separate application mentions. Proposal and follow-up sections are parsed separately, preserving real grant amendments and milestone decisions while keeping administrative discussion out of the preceding proposal. Older snapshots without HTML continue to use plain-text parsing.
Important boundaries:
- The operational Google Sheet has 24 documented tabs; only two are mirrored by default.
- The configured All Grants dataset derives source identity from the normalized,
nonblank
Grant Platform Linkcell. This identity strategy is explicit dataset configuration rather than inferred from a column header. Duplicate identifiers fail the mirror before any database mutation. The legacyNAcell is retained as an opaque identifier because it is currently unique; a secondNAwould fail the same duplicate guard. Row number remains mutable locator metadata and does not own the current record. - Canonical application matching also uses the platform identifier, rather than
title, applicant, or JSON field order. GitHub issue links are compared by
owner/repository/issue, with comment fragments identifying the same application.
Submission dates are read from
Date Submitted. Existing historical keys and IDs are reused by their stored primary platform link; an active manual-decision owner takes precedence over an unreviewed duplicate. Conflicting reviewed owners stop reconciliation before generated data is changed. Older duplicate records are retained for separate, reviewed cleanup rather than deleted during matching. Full and targeted reconciliation share the same GitHub planning code. - An explicit All Grants GitHub issue link also identifies an application when
its title and labels no longer contain
Grant. Newly linked issues reuse the existing registry application ID; established GitHub applications retain their existing identity.Closed - Did Not Follow Processis retained as the closure label and normalizes tofiltered, without entering committee review. If the GitHub source disappears, targeted reconciliation immediately restores surviving registry evidence and clears obsolete GitHub state and labels. If the registry row disappears first, the persisted GitHub source owner keeps the same application ID. If both sources disappear, either full or targeted reconciliation retains the application asunknownfor review. source_recordsremains the current projection used by canonical and retrieval queries. Every inserted, changed, moved, re-keyed, or removed source state appends a newsource_record_observationsversion. Identical repeats do not create duplicate versions, and authoritative pruning cannot erase the append-only history.- FPF assignment is authoritative for the committee-review stage. An application
is normalized to
under_reviewonly when its GitHub issue has both theGrant ApplicationandReady For ZCG Reviewlabels. A Sheet review value is retained as evidence and produces a reconciliation warning, but cannot promote an application into the committee worklist by itself. - A
grant_applicationrepresents a proposal broadly. Agrantis created only for applications normalized toapproved,active, orcompleted. Reconciliation also deletes an existing grant row if its processed application later becomes declined, withdrawn, cancelled, or otherwise leaves those funded statuses. - Matched rows from the
ZCG Grantsmilestone-detail tab are normalized into read-only milestone and disbursement records while retaining the original Sheet row, URL, match confidence, and linkage method. Automatic projections require a strong reconciliation match; reviewer-confirmed links are also eligible. Ambiguous rows remain reconciliation issues rather than being silently attached. - Payment ownership preserves phase, quarter, year, and revised-proposal markers. Declined or withdrawn resubmissions do not receive automatic ledger links. A unique reviewer-confirmed owner takes precedence; competing eligible owners remain unresolved. Targeted updates load the connected applications, including previous owners, and recompute and reindex all affected applications.
- Requested amounts come from proposal evidence, never the largest ledger row. Funding totals sum uniquely owned ledger installments, including startup funding and split payments. The schedule can represent a partial approval (for example, milestone 1 only), so it is kept separate from the full request and disbursements. Refunds and reimbursements are recorded separately; missing amounts, unresolved ownership, and negative ordinary milestone adjustments leave the total unconfirmed. The detail page and retrieval summary expose this basis.
- The Sheet's
Amount (USD)row value is not treated as a disbursement. A disbursement row is created only when the Sheet explicitly records a paid date, ZEC amount, or USD-disbursed amount. No payment-request, approval, progress-update, or on-chain-settlement state is inferred from those fields. - Linked application Forum topics can mirror up to 1,000 posts by default; Community Grants Updates topics default to 20 posts per topic.
- S3 snapshots are optional. When no snapshot bucket is configured, raw payloads
still live in PostgreSQL
source_records.
| Route | Purpose | Access |
|---|---|---|
/dashboard |
Clean committee worklist for applications under review, direct grant and briefing links, and a full application registry that is collapsed by default | Public read-only mode; authenticated operations depend on role permissions |
/admin/grants/:id |
Application details, FPF milestone/disbursement ledger, labels, linked evidence, decision history, and committee/custom grounded analysis | Core evidence and published shared briefings are public; reconciliation details and private reports require authentication and permissions |
/briefings/:id |
Dedicated, citation-grounded committee briefing with links back to its grant and the dashboard | Public when the shared briefing completed successfully and has content |
/admin/knowledge |
Keyword, semantic, hybrid, and grounded evidence search with an explanation of the selected retrieval and answer modes | Public evidence summaries can use all retrieval modes; anonymous semantic and hybrid searches have usage controls and keyword fallback; AI-composed answers require permissions |
/admin/telemetry |
Source, reconciliation, corpus, index, embedding, provider, and aggregate anonymous-search status | Authenticated operational roles |
/admin/reconciliations |
Review and persist ambiguous source-to-application decisions | Authenticated roles with reconciliation access; writes require reconciliation write access |
/admin |
Protected administrative overview | Administrator-authorized users |
/admin/users |
Email and domain role grants | Administrator-authorized users |
PUBLIC_PROTOTYPE_READONLY=true exposes selected server-rendered dashboard,
grant-detail, published committee-briefing, and keyword-search views. It does
not expose telemetry, reconciliation operations, user management, indexing,
embedding, synchronization, AI answer composition, private reports, or writes.
Public evidence summaries may use semantic or hybrid retrieval when embeddings
are configured. Those anonymous embedding requests are limited per client and
across each UTC day, fall back to keyword retrieval when a limit is reached,
and produce only aggregate usage telemetry without query text or network
addresses.
Each completed committee briefing saves the exact cited knowledge records and their content hashes. When the briefing is viewed, the system compares only those saved records with the current knowledge index; unrelated corpus changes do not make the briefing stale. A cited record whose hash changed is marked Changed since briefing, while a saved record that is absent from the current index is marked No longer indexed under Evidence and citations. Template or model changes are reported separately as a briefing update being available.
Source synchronization and knowledge indexing never rewrite or automatically regenerate an existing briefing. An authorized reviewer decides whether the identified changes are material enough to regenerate. Regeneration invokes the configured AI provider, which can incur provider cost, and creates a new version while preserving the prior briefing and its citation snapshot in history.
Committee briefings use standard Astra through Venice (openai-gpt-6-astra)
with explicit medium reasoning. Custom analyses and knowledge answers retain
their separate GPT-5.5 default. ZCG_KNOWLEDGE_COMMITTEE_BRIEFING_MODEL overrides
only the committee model; ZCG_KNOWLEDGE_AI_MODEL controls the other paths.
The committee request omits sampling parameters and allows 25,000 completion
tokens, including reasoning, with a four-minute provider timeout. The existing
1,400-word prompt and 24 KB storage limit still bound the final briefing. The
answer Lambda allows seven minutes for retrieval, generation, and persistence;
each model request reserves 30 seconds of remaining execution time for saving
success or failure. Generation remains asynchronous with browser polling.
ZCG_KNOWLEDGE_AI_TIMEOUT_MS continues to control the other answer paths.
Saved reports record input/output tokens, reasoning tokens when supplied by the provider, effective request settings, and provider latency. Refused, incomplete, or truncated committee responses fail generation. Existing saved briefings remain versioned and show a model update available; changing models does not regenerate them. See the model release runbook.
- Web: Next.js 15, React 19, and TypeScript. The live web tier runs on AWS Amplify SSR and reaches private Aurora through an IAM compute role and the RDS Data API.
- Database: Aurora PostgreSQL 16.13 with pgvector. Local development can use
PostgreSQL directly through
pg; serverless routes and knowledge workers can use the Data API. - Source workers: Lambda or local workers fetch public GitHub, Google Sheet, and Forum data, store optional snapshots in S3, and write source evidence to PostgreSQL.
- Knowledge workers: deployed index, embedding, and asynchronous answer workers use the Data API. Embeddings and answer composition use a configurable OpenAI-compatible endpoint.
- Authentication: Better Auth sends a single sign-in email containing both a secure magic link and a one-time code through SES in deployed environments. When SES is unset locally, the link and code are logged to the server console.
- Scheduling: a Standard Step Functions pipeline runs every morning at 3:00 AM
America/New_York. It mirrors configured public sources in bounded GitHub and Forum batches, reconciles canonical applications, and waits for a knowledge- index rebuild. The Admin Refresh corpus control starts this same full workflow. A shared durable lease serializes every source-mutation path; a full run waits for a targeted or Sheet update but skips when another full run already owns the lease. The embedding worker catches up new or changed documents on its hourly schedule. - Incremental refresh: a public-but-signature-verified callback Lambda accepts GitHub and Discourse events, buffers them in encrypted SQS, and runs targeted source mirroring, GitHub-application reconciliation, and affected knowledge- document updates at single concurrency. A separate non-VPC workflow checks the two public Google Sheet CSV exports every 15 minutes and enters the shared refresh pipeline only when their deterministic content checksum changes. Its S3 checksum marker advances only after mirroring, authoritative Sheet-row pruning, reconciliation, newly discovered Forum mirroring, and indexing succeed. Google Drive notifications remain supported but dormant; no Drive watch or Google service-account key is required. All incremental paths retain the Admin and daily full-refresh safety nets.
| Path | Purpose |
|---|---|
app/ |
Next.js pages, layouts, and route handlers |
app/dashboard/ |
Public dashboard entry point |
app/admin/ |
Dashboard, grant details, telemetry, reconciliation, knowledge, and user access UI |
app/briefings/ |
Public pages for successfully published shared committee briefings |
app/api/ |
Health, auth, administration, synchronization, and public API routes |
lib/source-mirroring/ |
GitHub, Google Sheet, and Forum collectors plus source storage |
lib/reconciliation/ |
Canonical grant reconciliation, durable reviewer decisions, and meeting-minute parsing |
lib/knowledge/ |
Knowledge documents, retrieval, embeddings, answer jobs, and composition |
lib/admin/ |
Dashboard and user-management data access |
lib/auth.ts and lib/authorization.ts |
Authentication and server-side permission enforcement |
workers/ |
Sync, migration, knowledge index, embedding, and answer workers |
migrations/ |
Better Auth, authorization, source, canonical, decision, and retrieval schema |
infra/ |
AWS CDK backend stack |
tests/ |
Reconciliation, knowledge, briefing, and source-mirroring tests |
docs/ |
Discovery, architecture, migration, reconciliation, and deployment notes |
- Node.js 24.x; repository tooling and containers currently pin
24.18.0. - npm 11.
- PostgreSQL 16 with the
pgvectorextension available.
An optional local database using Docker:
docker run --name zcg-postgres \
-e POSTGRES_USER=zcg \
-e POSTGRES_PASSWORD=zcg \
-e POSTGRES_DB=zcg \
-p 5432:5432 \
-v zcg-postgres:/var/lib/postgresql/data \
-d pgvector/pgvector:pg16npm ci
cp .env.example .envBefore continuing, set a strong BETTER_AUTH_SECRET in .env. To receive the
Administrator role on first sign-in, also set BOOTSTRAP_ADMIN_EMAILS to your
email address. The default DATABASE_URL matches the optional Docker database
above.
Standalone scripts and workers read process environment variables directly;
they do not load .env themselves. Export the file before running migrations or
workers:
set -a
source .env
set +a
npm run db:migrate
npm run devOpen http://localhost:3000/sign-in and request a sign-in email. With
SES_FROM_EMAIL unset, both the secure sign-in link and one-time code appear in
the development-server console.
npm run db:seed is a legacy/manual seed path and requires SEED_ADMIN_EMAIL.
For a normal Better Auth sign-in, prefer BOOTSTRAP_ADMIN_EMAILS as described
above.
For local development, the compatibility command can still mirror, reconcile, rebuild the knowledge index, and optionally embed documents:
Reliable full-corpus GitHub comment mirroring requires GITHUB_TOKEN or
ZCG_GITHUB_TOKEN with read-only Issues access; anonymous API rate limits are
usually too low for this workflow.
npm run worker:sync -- --reconcile
npm run knowledge:index
npm run knowledge:embedThe deployed Admin action and daily schedule use the bounded Step Functions pipeline instead of the compatibility command so growth in GitHub issues or Forum topics cannot exceed one Lambda invocation's runtime limit.
The deployed hybrid path can also process signed GitHub and Discourse callbacks for only the affected issue, topic, application, and knowledge documents. The deployed Sheet poll checks public exports without waking Aurora when content is unchanged and runs a Sheet-only refresh when it changes. These paths are additive: the full Admin and scheduled workflows remain available while source callbacks and polling are proven. See the hybrid corpus refresh runbook.
The embedding command requires a configured embedding API key. Keyword search works without embeddings or AI answer composition.
Administrators can run the same deployed sequence from Admin → Source corpus → Refresh corpus or Knowledge → Corpus maintenance → Refresh corpus. Rebuild index is intentionally narrower: it only regenerates searchable documents from canonical applications already in the database and does not fetch new GitHub, Google Sheet, or Forum records.
Useful maintenance commands:
npm run reconcile:grants
npm --silent run reconciliation:export > data/reconciliation-decisions.json
npm run reconciliation:import -- ./data/reconciliation-decisions.json
npm run worker:knowledge-index
npm run worker:knowledge-embed
npm run infra:synthRun the automated reconciliation, knowledge, and source-mirroring tests with:
npm testRun the static and production-build checks with:
npm run checkcheck runs TypeScript checking, ESLint, and a production build.
Every change requires an independent agent review before merging or triggering
any deployment, including an automatic deployment from a push to main. Follow
the review and release workflow in AGENTS.md:
review immutable base/head commits, resolve blocking findings, and verify the
final revisions and validation results before release. This is an agent workflow
requirement; GitHub and AWS enforcement are not configured by this guidance.
The current public deployment combines:
amplify.ymlfor the Amplify SSR web tier atzcg.pgpz.org;- private Aurora PostgreSQL with the RDS Data API;
- an encrypted, versioned, non-public S3 snapshot bucket;
- Lambda workers for migration, synchronization, indexing, embedding, and grounded answer jobs;
- an authenticated webhook ingress, encrypted SQS event queue, dead-letter queue, and single-concurrency targeted corpus worker;
- a non-VPC Google Sheet checksum worker and changed-Sheet Step Functions workflow, scheduled every 15 minutes by default;
- Secrets Manager, IAM roles, CloudWatch logs, and optional alarms; and
- an optional ECS/Fargate and load-balancer web path for production-style deployments.
Two CDK cost modes are available: prototype-low-cost, which omits the optional
ECS/ALB web tier and permits Aurora scale-to-zero, and production-ready, which
restores production-style web compute, minimum database capacity, monitoring,
and alarms.
Preview and deploy the current low-cost prototype with the repository's named AWS profile and region:
AWS_PROFILE=zodldashboard AWS_REGION=us-east-1 \
npm run infra:diff:prototype-low-cost -- \
--profile zodldashboard --region us-east-1
AWS_PROFILE=zodldashboard AWS_REGION=us-east-1 \
npm run infra:deploy:prototype-low-cost -- \
--profile zodldashboard --region us-east-1 --require-approval neverSee AWS account portability, Amplify target, backend connection, and deployment cost modes. Callback registration and transition steps are in the hybrid corpus refresh runbook.
- Preserve public trust. Existing public records should remain available and traceable during any migration.
- Migrate before replacing. Read-only mirroring and explicit reconciliation should precede writeback or cutover.
- Make provenance first-class. Store source IDs, URLs, checksums, payloads, confidence, relationship roles, and reviewer rationale.
- Surface uncertainty. Unmatched rows, ambiguous titles, stale state, and missing links belong in a review queue rather than being hidden.
- Separate public and private data. KYC, agreements, payment instructions, custody, and internal deliberation require explicit private boundaries.
- Publish from allowlists. Public APIs and views should expose deliberate projections rather than raw operational rows.
This public repository must not contain production secrets or private
operational data. .env.example contains placeholders only; local environment
files and account-specific CDK context are ignored.
- Add durable progress-update, payment-request, and approval objects once the authoritative source fields and identifiers are agreed; do not infer those workflow states from the FPF disbursement ledger.
- Add reviewer-assisted status normalization and richer decision-link review.
- Decide whether and how to mirror Jotform, website content, and approved private operational records.
- Enrich normalized milestones with durable cross-source grant/milestone IDs and, where publishable, payment-request or transaction references supplied by the authoritative systems.
- Promote stable public grant URLs and exports from explicit projections; the
current public grant details still live under the prototype's
/admin/grantsroute structure. - Add applicant and FPF/ZCG workflow surfaces only after source confidence and privacy boundaries are agreed.
- Complete post-deploy cutover observation for the administrator-configured GitHub and Discourse callbacks, monitor the 15-minute public Sheet poll and 3:00 AM verification run, and treat a Google Drive watch as an optional future experiment. Define future writeback, archive, and rollback policies separately.
The architectural assessment contains the fuller target-system argument and proposed architecture.
- Current-state discovery
- Architectural assessment
- Prototype development plan
- Phase 0 build checklist
- Phase 1 source mirroring
- Manual reconciliation decisions
- Committee grant briefing plan
- Deployment cost modes
- Hybrid corpus refresh
- AWS account portability
Except as otherwise noted, original project-authored software, documentation, and other original repository materials are licensed under the GNU Affero General Public License, version 3 only.
The corresponding SPDX expression is AGPL-3.0-only.
This project license does not relicense mirrored or imported records, grant materials, source excerpts, applicant content, third-party assets, or names, logos, and other marks. See Third-party notices for the applicable boundaries and the OpenZcash favicon attribution.
Unless you explicitly state otherwise, any contribution intentionally
submitted for inclusion in this project is licensed under AGPL-3.0-only,
without additional terms or conditions.
If you discover a security issue, do not open a public issue containing exploit details. Contact the repository owner privately until a formal security policy is added.
