Proposer Instructions

The SCF Public Goods Award provides quarterly funding for maintenance, security, and incremental evolution of open-source public goods in the Stellar ecosystem. This page walks proposers through the full lifecycle — from intake eligibility through proposal submission, community review, on-chain voting, award distribution, and renewal.

Intake Process (Rolling Admissions)

The intake process determines whether a project is eligible to submit a formal proposal. Intake is always open — there is no deadline. Projects can submit an intake form at any time, and approved projects can submit a proposal in the next available quarterly round.

How It Works

  1. Submit the Intake Form. Open a new Intake Form issue in this repository.
  2. Automated validation. The form is validated automatically. If there are errors, the bot will flag them and you can edit your issue to fix them.
  3. Eligibility discussion. Once validated, your intake enters the pg-intake:in-review state. SCF members — especially Pilots — discuss your project in the issue thread. This period lasts a minimum of 7 days. Pilots signal their position by reacting with 👍 or 👎.
  4. Quorum check. A Pilot runs the .quorum-check command. The bot counts pilot reactions:
    • Minimum 3 voters required.
    • Acceptance formula: ups ≥ 3 + 2 × downs (each downvote raises the bar by 2 upvotes).
  5. Decision. The issue is labeled pg-intake:accepted or pg-intake:rejected, then closed and locked. If rejected, only Pilots can reopen the intake and discussion.

Once accepted, you are eligible to submit a proposal in the next quarterly round.

flowchart TD
    %% VALIDATION PHASE
    Submit["Proposer submits\nIntake Form\n(GitHub Issue)"] --> Validate["Automated validation\n(issue-ops parser + validator)"]

    Validate -->|"valid"| ReadyReview["Label: pg-intake:in-review\nBot posts: Ready for Eligibility Review"]

    Validate -->|"invalid"| ValidationError["Label:\nissueops:validation-error\nBot posts error comment"]
    ValidationError --> EditIssue["Proposer edits issue\n(triggers re-validation)"]
    EditIssue --> Validate

    %% DISCUSSION & QUORUM PHASE
    ReadyReview --> Discussion["SCF members discuss\n(≥7 days)\nPilots react 👍 / 👎"]
    Discussion --> RunQuorum["A Pilot runs\n.quorum-check command"]

    RunQuorum --> CheckQuorum{"Quorum met?\n(≥3 voters)"}
    CheckQuorum -->|"No"| NotEnoughVotes["Bot: not enough votes yet"]
    NotEnoughVotes --> Discussion

    %% DECISION PHASE
    CheckQuorum -->|"Yes"| CheckApproval{"Accepted?\n(ups ≥ 3 + 2 × downs)"}

    CheckApproval -->|"Yes"| IntakeAccepted["Label: pg-intake:accepted\nIssue closed & locked"]
    CheckApproval -->|"No"| IntakeRejected["Label: pg-intake:rejected\nIssue closed & locked"]

    IntakeAccepted --> EligibleStatus["Proposer is now eligible\nto submit a Proposal"]
    IntakeRejected --> ReopenRules["Only Pilots can reopen the\nintake and discussion"]

Proposal Process — Quarterly Timeline

Eligibility: Only projects approved through intake or through previous Award participation may submit the proposal form. Ineligible use of the form is publicly visible.

Phase Description Duration
1️⃣ Proposal Submission Proposer fills out the Proposal Form (GitHub Issue). Automation validates the submission, generates a project page, and creates a Pull Request. The issue is closed with a link to the PR. For renewals, see below. Quarterly window
2️⃣ Discussion & Revisions (D&R) Community reviews the proposal PR on GitHub. Proposer edits the project page directly on the PR branch; the PR description auto-syncs on every commit. Previous deliverables are also reviewed during this phase. Early entrants have more time for revisions; late entrants have less. ~7 days
3️⃣ On-chain Submission At the close of the D&R window, revised proposals are submitted to Tansu for on-chain voting. Within 2 business days
4️⃣ On-chain Vote SCF Pilots vote on proposals using NQG-weighted scores on Tansu. ~3 days
5️⃣ SDF Compliance & Payout Setup After community approval, SDF performs a final compliance check. At SDF’s discretion, if a community-approved proposal does not meet Award eligibility, the project is not awarded. ~1 week
6️⃣ Award Distribution — Tranche 1 First 50% of the award is distributed after approval and payment setup. ~1 week
7️⃣ Award Distribution — Tranche 2 Second 50% is distributed after reviewers approve previous deliverables (supermajority required). Next quarter
flowchart TD
    %% SUBGRAPH: INTAKE
    subgraph NewProposal ["New Proposal"]
        direction TB
        IntakeForm["Proposer fills out\nProposal Form\n(GitHub Issue)"] --> GenesisAction["🤖 Genesis Action:\n1. validate\n2. render project page\n3. create branch + PR\n4. close issue"]
    end

    %% SUBGRAPH: RENEWAL
    subgraph RenewalFlow ["Update and optional Renewal Proposal"]
        direction TB
        EditPage["Proposer edits\nexisting project page"] --> RenewalPR["Opens PR from new branch:\nproposals/{slug}-{quarter}"]
    end

    %% PR ENTRY
    GenesisAction --> ProposalPR
    RenewalPR --> ProposalPR
    ProposalPR["Proposal PR open\non GitHub"] --> |"D&R phase starts"| DiscRev

    %% DISCUSSION & SYNC (Stacked Vertically)
    subgraph DiscussionPhase ["Discussion & Revisions Phase"]
        direction TB
        DiscRev["Discussion & Revisions\n(~7 days)\nCommunity reviews on PR"]
        SyncAction["🤖 Sync Action:\nPR body updates on each commit"]
        DiscRev <--> SyncAction
    end

    %% DELIVERABLES BRANCH (Semantic: Branches from Discussion)
    DiscRev --> CheckDeliverables{"Has previous\ndeliverables?"}

    subgraph DeliverablesReview ["Deliverables Review"]
        direction TB
        CheckDeliverables --> |"Yes"| RevReview["Reviewers approve\n or comment"]
        RevReview --> Supermajority{"Supermajority\napproves?"}
        Supermajority --> |"Yes"| Tranche2["Tranche 2: 50% \ndistributed(~1 week)"]
    end

    %% VOTING PATH (Semantic: Follows D&R End)
    DiscRev --> |"D&R phase ends"| Finalized["Proposal finalized\n(D&R window closed)"]

    Finalized --> TansuVote["Proposal PR merged\nand automatically submitted to\nTansu for on-chain vote"]
    TansuVote --> PilotsVote["SCF Pilots vote\n(NQG-weighted, ~3 days)"]
    PilotsVote --> VoteOutcome{"Approved?"}

    %% FINAL OUTCOMES
    VoteOutcome --> |"Yes"| Compliance["Handoff to SDF for\ncompliance check"]
    VoteOutcome --> |"No"| Rejected["Proposal not awarded"]

    Compliance --> ComplianceOutcome{"SDF compliance\npassed?"}

    ComplianceOutcome --> |"Yes"| Tranche1["Tranche 1: 50% distributed\n(~1 week)"]
    ComplianceOutcome --> |"No"| SDFRejected["Project not awarded\n(at SDF discretion)"]

    %% NEXT QUARTER LOOP
    Tranche1 --> |"Next quarter"| EditPage

Filling Out the Proposal Form

The Proposal Form is mostly self-explanatory. A few things to keep in mind:

  • Project Name is used to generate the URL slug for your project page (e.g., “StellarExpert Explorer” → stellarexpert-explorer). Choose a clear, recognizable name.
  • PG Intake Form — link to your approved intake issue. If you submitted through Airtable during the soft-launch period, write “soft-launch”.
  • Maintenance Reserve and Other — the two parts of your ask, together capped at $50,000 in XLM per quarter. The maintenance reserve is capacity you are holding for work that arrives during the quarter; Other covers your named deliverables. See Budget Allocation for where the line sits. Your total should be reasonable relative to your retroactive impact and planned deliverables.
  • Legal Acknowledgements — you must agree to the Legal Acknowledgements provided by SDF. This is required to proceed.

Tip: Links in the form open in your current browser tab by default. Draft your answers in a separate file first, or copy them as a backup before submitting.

There are a couple of changes you should make immedately after the Proposal Form issue is closed.

Discussion & Revisions (D&R)

After you submit the Proposal Form, automation creates a Pull Request containing your project page and closes the issue with a link to the PR. From that point on, the PR is your proposal.

Additions to Make Before D&R Starts

  • Public Git Repository — the form takes one repository, which becomes the Repository row in your project page table. If your project spans more than one repository, add a row for each additional repo to the table. PG Atlas reads this table, so any repository left out is missing from your project’s metrics.
  • Health endpoint — if your project runs a hosted service, add a health_endpoint line to your project page front matter, pointing at a public URL that returns a success response while the service is up. The program polls it, so you never have to report uptime yourself. The endpoint does not need to be live when you add it to your proposal: the first 2xx data point marks the beginning of the uptime calculation.
  • Metrics endpoint — if the work you are funded for does not land in a git repository, add a metrics_endpoint line to your project page front matter pointing at a public URL returning counts you consider meaningful, as JSON. Reports logged, datasets published, records curated: whatever your quarter is actually measured in. The program polls it, so your progress is visible without you having to assemble it. As with the health endpoint, the URL does not need to resolve yet when your PR is merged.

How to Make Revisions

  1. Go to your PR and navigate to the “Files changed” tab.
  2. Click the pencil icon (Edit) on your project page file.
  3. Make your changes and commit them directly to the PR branch.

Every commit automatically updates the PR description to stay in sync with your project page. You can also clone the branch locally and push changes using git.

Review Process

  • Community members and reviewers (SCF Pilots) leave feedback directly on the PR using comments and GitHub’s Suggest Changes feature.
  • When you accept a suggested change, it counts as a commit, so the PR description updates automatically.
  • All formal discussion and feedback happens on the PR. We encourage you to also post a thread in #projects on the Stellar Developers Discord for broader informal discussion, which can continue outside of the Public Goods Award quarterly cycle.

Renewals

Projects that received a previous Award do not fill out the Proposal Form again. Instead, you update your existing project page directly:

  1. Navigate to your project page in the docs/projects/ directory on the main branch.
  2. Click the Edit (pencil) icon on your project page.
  3. Update the relevant sections: next-quarter goals and updated budget. Give the budget as three rows in the summary table, so a renewal carries the same split as a new proposal:

    | **Budget Requested**    | $15,000 |
    | **Maintenance Reserve** | $12,000 |
    | **Other**               | $3,000  |
    

    The two parts sum to the total; see Budget Allocation for where the line sits. Update the budget: front matter value with your new total. Retroactive impact and deliverable evidence are not part of a renewal — they go in that quarter’s deliverables submission.

  4. Choose “Create a new branch for this commit and start a pull request.”
  5. Name your branch following the convention: proposals/{slug}-{quarter} (e.g., proposals/stellar-sdk-2026q3).

Because the sync automation triggers on any PR that modifies files in docs/projects/, your PR description will automatically populate with the content of your updated project page. The renewal PR then goes through the same Discussion & Revisions → On-chain Vote → Payout cycle as new proposals.

Quarterly Deliverables

Projects that received a previous Award submit evidence of completed deliverables separately from the proposal for the next quarter. As with renewals, you update your existing project page directly:

  1. Navigate to your project page in the docs/projects/ directory on the main branch.
  2. Click the Edit (pencil) icon on your project page.
  3. Update ## Retroactive Impact to cover the quarter you are reporting on. This section is rewritten each quarter rather than added to; previous versions remain in the page history.
  4. Under ## Past Deliverables, add a new ### {Year} Q{N} subsection. Start it with the budget allocation table described below, then give evidence for each deliverable you committed to in that quarter’s proposal, as #### subheadings. Leave previous quarters in place.
  5. Choose “Create a new branch for this commit and start a pull request.”
  6. Name your branch following the convention: deliverables/{slug}-{quarter} (e.g., deliverables/stellar-sdk-2026q3).

Because the sync automation triggers on any PR that modifies files in docs/projects/, your PR description will automatically populate with the content of your updated project page. The deliverables PR is reviewed against the deliverables you committed to in that quarter’s proposal; approval by a supermajority of reviewers releases Tranche 2.

Budget Allocation

Maintenance is funded as reserved capacity, not as a task list. Most of it arrives during the quarter — bug reports, security fixes, toolchain breaks, late changes to a protocol release — so it cannot be costed in advance the way a named deliverable can. What you set in advance is how much of the award you are holding for it.

Your proposal declares that reserve. Each quarter’s deliverables then open with a table comparing what was reserved against what was actually spent:

Budget allocation Reserved Actual
Maintenance $12,000 $11,200
Other $3,000 $3,800

Use dollar amounts rather than percentages. Each column should sum to the award for that quarter. Enter $0 rather than leaving a cell blank. Where your proposal predates this table, leave Reserved empty and fill in Actual only.

Coming in under your maintenance reserve is not something to hide. The two columns exist so that an efficient quarter reads as an efficient quarter, rather than being rounded to match the reserve.

What counts as maintenance

Maintenance is work that would still be needed if nobody asked for anything new. That sentence is the test. The list below is examples of it, not a closed set:

  • bug fixes, security patches, and dependency updates;
  • protocol-compatibility work;
  • platform and toolchain updates that keep the package installable and building;
  • fixes to specifications you already implement, and updates when one of those is revised;
  • compatibility matrices, CI and test upkeep, and release engineering;
  • documentation of existing behaviour, issue triage, and user support.

Other is the remainder of the award: anything the definition above does not cover. It is a complement rather than a category, so the only question to settle is whether something is maintenance.

Three cases are easy to get wrong:

  • Supporting a new protocol version is maintenance, even when it is entirely new code. An SDK that cannot load a contract deployed under the active protocol is broken, not feature-poor.
  • A rewrite is maintenance, however large, if it leaves the project doing the same things.
  • Implementing a specification you did not previously support is Other, even though maintaining it afterwards is maintenance.

Access & Permissions

Proposers need to be added to the GitHub team corresponding to their SCF membership role. Those that are not SCF Pilots are added to the pg-maintainer team to get the write permission needed to create and edit PRs without forking.

If you do not have write access to this repository, contact an active SCF Pilot or SDF representative to be added to the appropriate team before submitting your proposal.


Back to top

This site uses Just the Docs, a documentation theme for Jekyll.