You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Replace today's "open a PR against project_ideas.md" intake with a GitHub Issue Form + a small set of GitHub Actions workflows that:
lower the barrier for maintainers/mentors to submit a proposal (web form, no git knowledge),
validate the submission automatically (format checks now; LFID/email verification once we coordinate with the LFX platform team),
track each program (not each PR) through the lifecycle on Project board #92,
produce a machine-readable artifact the LFX platform team can ingest in bulk instead of us re-keying every field by hand.
This issue is a discussion document. Feedback welcome from maintainers, mentors, the LFX Mentorship platform team, and CNCF program admins. See §10 How to give feedback at the bottom.
Authored by @nate-double-u with assistance from Copilot CLI.
1. Problem
The current intake process for each LFX Mentorship term requires maintainers and prospective mentors to open pull requests against programs/lfx-mentorship/<year>/<term>/project_ideas.md, adding a free-form markdown block per program. This is painful in three ways:
High barrier for proposers. Maintainers must understand git/PR mechanics to propose a program, even when they have no other reason to touch the repo.
High overhead for the program admin. Each accepted program must be re-keyed (or copy-pasted) into the LFX Mentorship platform by hand, field by field, from prose markdown.
Mismatched lifecycle tracking.Project board #92 tracks each PR through an 11-stage status pipeline, but the actual unit of work is a program — and a single PR often contains several programs. The board and the reality drift apart after merge.
2. Goals
Lower the barrier for maintainers/mentors to submit a program proposal.
Produce a machine-readable artifact per term that the LFX platform team can ingest in bulk (or that we can ingest via an API, eventually).
Track each program (not each PR) through the existing project-board lifecycle.
Catch the most common data-quality failures — wrong mentor email, malformed upstream URL — before a human reviews the proposal.
3. Non-goals
Replacing the LFX Mentorship platform itself.
Automating selection of mentees (still owned by mentors / LFX).
Building anything Outreachy- or GSoC-scale (custom web app, applicant DB).
4. Proposed approach
4.1 Intake: GitHub Issue Form
A new .github/ISSUE_TEMPLATE/lfx-program-proposal.yml form replaces the
near-empty existing template. Each submitted issue represents one program proposal.
Fields (subject to refinement once LFX import schema is known):
Field
Type
Required
Notes
CNCF Project
dropdown
✓
Generated from cncf/landscape. See §4.2.
Term
dropdown
✓
Current + next two terms. Value is the bare token (e.g. 2026 Term 1); months shown as helper text.
Program Name
input
✓
Bare middle of LFX Program Name; export composes the full convention. See §4.1.2.
Program Description
textarea
✓
Up to 3000 characters. Maps directly to LFX's single Program Description field. Use placeholder/sample text in the form to prompt for both Description (what the program is) and Expected Outcomes (what success looks like) within the single field — see §4.1.5.
Technologies
input
✓
Comma-separated. Maps to LFX Step 1 "Technologies" chips.
Required/Desirable Skills
input
✗
Comma-separated. Maps to LFX Step 2 "Required and/or desirable skills and training" chips. Leave blank if same as Technologies (and keep the checkbox above checked).
Skills same as Technologies?
checkboxes
✗
Single checkbox, default checked. If checked, the field below may be left blank and the export uses Technologies for both. See §4.1.4.
Mentors
textarea
✓
One mentor per line. Format: Full Name | @github-handle | lfid-email. The first line is the primary mentor; subsequent lines are additional mentors. See §4.1.3 for rationale and validation.
Upstream Issue URL
input
✓
Exactly one URL. If the program covers multiple issues, create an umbrella issue upstream and link to that. Validation rejects multiple URLs. Maps to LFX's Repository URL field on export — see §4.1.1.
Application Requirements
checkboxes
✗
Common patterns: writing sample, project proposal, code/portfolio link. All treated as required. See §4.7.
Additional Application Requirements
textarea
✗
Free-form for anything not covered above. Configured manually on LFX as required items.
Auto-applied labels on submission: lfx mentorship, proposal, needs-validation.
Why one issue per program (not one issue per maintainer with multiple programs):
The project-board lifecycle is per-program. Bundling forces multiple programs into one row and re-creates today's mismatch.
4.1.1 Mapping to the LFX platform wizard
The form fields above are designed to populate LFX's program-creation wizard
(see screenshots attached to this issue). Important constraints learned from
the LFX UI:
LFX wizard field
LFX limit / type
Our form field
Notes
Program Name
100 chars, plain text
Program Name (bare middle only — see below)
Form collects only the program name; export composes CNCF - <Project name>: <program name> (<term>).
Linux Foundation Open Source Project
dropdown, parent foundation only
(none — implicit)
"CNCF Project" on our form is for our own labeling, not an LFX field.
Technologies (chips)
multi-chip
Technologies
Parsed from comma-separated input.
Program Description
3000 chars, rich text
Program Description
1:1 mapping. The form field has the same 3000-char limit as LFX. Validation enforces it.
Repository URL
URL, required
Upstream Issue URL
The form's Upstream Issue URL field flows into LFX's Repository URL slot. This is what gives applicants a single landing point for the work — the issue (or umbrella issue, §4.1) is more useful than the project's root repo URL, which they can find from the Website URL anyway.
Website URL
URL, required
(auto-populated from landscape)
Required by LFX. Auto-pulled from cncf/landscape for the selected project. If landscape is missing the value, fix it upstream (in cncf/landscape) — don't add a manual-override field on our form.
CII / OpenSSF Best Practices Project ID
numeric, optional
(auto-populated from landscape)
Code of Conduct URL
URL, optional
(auto-populated from landscape, fallback to CNCF CoC)
Auto-pulled from cncf/landscape for the selected project. If landscape doesn't have one, default to the CNCF Code of Conduct — every CNCF project is bound by it regardless.
Required and/or desirable skills and training (chips)
multi-chip
Required/Desirable Skills (or = Technologies via checkbox)
Two separate fields; "Skills same as Technologies?" checkbox lets the proposer signal the common case (same set) without retyping. See §4.1.4.
Program Terms
list of {Name (50 char), Start Month, Start Year, End Month, End Year}
Term (dropdown)
Our dropdown selects one term; export translates to LFX's Term object.
Standard Prerequisites (Resume, Cover Letter, School Enrollment, Participation Permission, Coding Challenge)
toggle on/off, each with editable description
Application Requirements (checkboxes)
Our "Project Proposal" maps to enabling LFX Cover Letter. See §4.7.
Custom Prerequisite
Name 20 chars, Description 500 chars, Due Date, "requires file upload" flag
(term-wide, configured by admin)
LFC102 / Inclusive Community lives here. See §4.6.
Note on scope/sizing fields: CNCF LFX programs are full-time (~350 hours
across the term), so we deliberately don't ask for Difficulty or
Time Commitment on the form.
These are valuable for our own intake and project-board tracking, and the mentor list also seeds LFX's post-approval Mentors tab.
4.1.2 Program Name composition
CNCF programs follow a strict naming convention on LFX:
CNCF - <Project name>: <program name> (<term>)
Example: CNCF - LitmusChaos: Add Prometheus Metrics to Control Plane Service (2026 Term 1)
The fixed scaffolding consumes 23 characters plus the project name (and term):
CNCF - (7)
: (2)
( + ) around the term (3)
<term> itself (e.g. 2026 Term 1 = 11)
So for the typical <term> value of YYYY Term N (11 chars), the available
budget for the bare program name depends on the project name length:
Project name
Project name length
Program-name budget (within LFX's 100-char limit)
OTel
4
73
Koordinator
11
66
LitmusChaos
11
66
OpenTelemetry
13
64
kubernetes-sigs/headlamp
24
53
Form treatment: the issue form collects only the bare middle in the
"Program Name" field. The CNCF Project (§4.2 dropdown) and Term (§4.1
dropdown) supply the surrounding pieces. The export workflow (§4.5)
composes the full LFX Program Name value at export time. The validation
workflow (§4.3) checks that the bare program name fits within the budget for
the selected project and warns the author with a precise character count if
not. This both prevents truncation (as seen in the screenshot, where 98/100
chars chopped the front of "Native Support for AI Agent...") and eliminates
the naming-convention drift visible across recent PRs (Term 1 vs T1,
missing year, missing "CNCF -" prefix, etc.).
The Term dropdown values (§4.1) should produce just the <term> token
expected by the convention (e.g. 2026 Term 1), not a longer label including
months. If you want the months visible to the form author, render them as
helper text below the dropdown rather than as part of the option string.
4.1.3 Mentors field shape
We need three things per mentor: full name, GitHub handle, and the
email address tied to their LFID (transitional — once we can look up LFIDs
directly, the email column becomes the LFID).
GitHub Issue Forms don't support repeating field groups, so a variable-length
list of structured records has to live in a single textarea. We use one line
per mentor with a pipe-separated format:
Full Name | @github-handle | lfid-email
Example:
Jane Doe | @janedoe | jane@example.com
Sam Lee | @samlee | sam@example.com
The first line is the primary mentor; subsequent lines are additional
mentors. There is exactly one form field for both — no separate "Primary
Mentor" block — which keeps the data shape consistent across mentor counts
and avoids the awkward "why does the primary mentor get three fields but the
additional mentors only get a textarea" inconsistency.
Why pipe-separated, not comma-separated: names contain commas
("Smith, John, PhD"); pipes don't appear in real names, GitHub handles, or
emails, so parsing is unambiguous.
Validation rules (also reflected in §4.3):
At least one line (primary mentor required)
Each line has exactly 3 pipe-separated fields after trimming whitespace
Field 1 (name): non-empty
Field 2 (handle): matches @[A-Za-z0-9-]{1,39} (GitHub handle rules)
Field 3 (email): matches email regex
No duplicate handles or emails across rows
Dependency on the LFX team: the email-vs-LFID part of this design is
contingent on coordination with the LFX Mentorship platform team. Today
we collect "the email address used with their LFID" because that's what
we can verify by hand. Once LFX exposes an LFID lookup (see §5 Ask #1),
we'd switch this column to LFID directly and drop the email collection.
The textarea shape is designed to make that swap trivial — same field,
different per-line format.
4.1.4 Technologies vs. Required/Desirable Skills
The LFX wizard exposes two chip-style fields that look similar but live in
different wizard steps (see screenshots, §4.1.1):
Technologies (Step 1, Program Details): the technical surface area of
the program — languages, frameworks, platforms.
Required and/or desirable skills and training (Step 2, Program Setup):
what an applicant should know coming in.
In the common case these are the same set ("if the program is in Go on
Kubernetes, applicants need Go and Kubernetes"). In the less-common case
they diverge — e.g. a documentation program might be about a particular
codebase (Technologies = the project's language/stack) but only require
prose skills of the applicant (Skills = "technical writing, Markdown").
We collect both fields so we can populate the LFX wizard accurately, but
add a single checkbox "Skills same as Technologies?" (default checked)
so the proposer doesn't retype the same set in 90% of cases. Form behavior:
Checkbox checked + Required/Desirable Skills blank → export uses
Technologies for both wizard fields
Checkbox checked + Required/Desirable Skills also filled → validation
warns about the contradiction (likely user error); admin clarifies
Checkbox unchecked + Required/Desirable Skills blank → validation fails
("either check the box or fill in the field")
Checkbox unchecked + Required/Desirable Skills filled → export uses each
field as given
Issue Forms can't conditionally show/hide fields, so both inputs are always
visible; the checkbox is a signal the workflow reads at validation and
export time, not a UX trigger.
Open question carried forward (§5 Ask #7): whether these are truly
two LFX fields or one rendered twice. If LFX confirms they're the same
field, we can collapse this back to a single input and drop the checkbox.
4.1.5 Program Description prompt
LFX has one combined Program Description field (3000 chars). Mentors vary
on how they'd want to split that — some lead with outcomes, some with
context, some weave them together. Rather than impose a structure, we
collect a single field but use the form's placeholder/sample text to
prompt for both halves so nothing important gets dropped:
# .github/ISSUE_TEMPLATE/lfx-program-proposal.yml (excerpt)
- type: textareaid: program_descriptionattributes:
label: Program Descriptiondescription: | Up to 3000 characters. This is what applicants will see on LFX. Cover both what the program is about and what success looks like — use the structure below or your own.placeholder: | ## Description What the program is about, the problem it solves, and the context a candidate needs to understand the work. ## Expected outcomes What "done" looks like at the end of the term — concrete deliverables, contributions, or capabilities the mentee should have produced.value: ""validations:
required: true
The placeholder text appears greyed-out inside the textarea until the
proposer starts typing — so it shows the suggested structure without
forcing it. The description (above the textarea) gives the rules.
Validation enforces the 3000-char hard limit (§4.3) but doesn't enforce the
structure — proposers can use the suggested headings, their own headings,
or none at all.
4.2 CNCF Project dropdown — keeping it current
GitHub Issue Form dropdowns are static — options are baked into the form's
YAML at commit time, not fetched at issue-creation time. To keep the CNCF
Project dropdown in sync with reality without manual edits, a scheduled
workflow regenerates the form's options: block from the canonical landscape
data.
Source:landscape.yml in cncf/landscape.
Filter to category CNCF Graduated, Incubating, and Sandbox (i.e., active
CNCF-hosted projects), excluding archived projects and the many landscape
entries that are not CNCF-hosted (member companies, end-user companies, etc.).
That yields ~200 projects, well within issue-form dropdown limits.
Workflow shape:
Trigger: weekly cron + workflow_dispatch for ad-hoc refresh.
Steps: download landscape.yml → filter → diff against current options block in lfx-program-proposal.yml → if changed, rewrite the YAML and open a PR (or auto-commit, if low-risk).
Bot commits use the Assisted-by: trailer per CNCF convention.
Edge cases:
CNCF project sub-projects sometimes use LFX Mentorship. Real example: PR #1861 added a sigs.k8s.io/node-readiness-controller proposal. The dropdown should include an explicit Other / not yet listed option that reveals (via the validation workflow's bot comment) a freeform follow-up where the proposer explains. Avoids forcing edge cases through an overly-narrow dropdown.
Naming canonicalization. Use the landscape's name: field as-is so naming flows downstream consistently. (Examples in recent PRs include both kgateway and Kgateway — pick the landscape spelling and stick to it.)
Regeneration noise. Only commit when the filtered list actually changes.
4.3 Validation: GitHub Actions workflow
.github/workflows/lfx-proposal-validate.yml triggers on issues.opened / issues.edited for issues carrying the lfx mentorship + proposal labels.
It performs:
Format checks (immediate, no external deps):
Email regex on each mentor's email (transitional — see §4.1.3 on switching to LFID)
URL regex on upstream issue, plus a check that exactly one URL is provided (umbrella the work upstream if it spans multiple issues)
GitHub-handle regex on each mentor's handle
Per-line shape check on the Mentors textarea (3 pipe-separated fields per row; at least 1 row; no duplicate handles or emails — see §4.1.3)
Program Name length within the per-project budget (§4.1.2)
Program Description ≤ 3000 characters (LFX limit, §4.1.1)
Technologies / Skills consistency (§4.1.4): if "Skills same as Technologies?" is unchecked, Required/Desirable Skills must be non-empty; if checked, Required/Desirable Skills should be blank (warn if both are filled)
LFX checks (stretch — requires LFX cooperation; see "Asks of LFX" below):
Verify each mentor email maps to a registered LFID on the LFX Mentorship platform
Verify the CNCF project name is recognized on the LFX side
CNCF checks (no external dependencies; details in §4.3.1–§4.3.4):
Per-project per-term proposal quota (§4.3.1)
Maintainer / ContribEx approval status (§4.3.2)
Mentor confirmation tracking (§4.3.3)
CNCF Mentorship admin approval (§4.3.4)
Output:
Bot comment summarizing ✅ pass / ❌ block / ⚠️ warning checks. Upserted (one comment per issue, edited in place on re-validation).
Labels: validation-passed / validation-failed. needs-validation removed once a verdict exists.
Implementation note (security):
A draft of the validation workflow uses peter-murray/issue-forms-body-parser@v4.1.0 for body parsing. Recommend inlining the parser (~30 lines inside actions/github-script) for the production version to avoid a third-party supply-chain dependency in a workflow that will hold the LFX_API_TOKEN secret. If we keep the third-party action, pin to a full commit SHA, not a tag.
4.3.1 Per-project per-term proposal quota
CNCF projects are currently capped at 4–5 program proposals per term
(subject to change in future terms). Today this is enforced by program-admin
attention; we can move it into validation:
Source of truth: a small config file in this repo, e.g. programs/lfx-mentorship/quotas.yml with a global default and per-project
overrides:
default_per_project_per_term: 5overrides:
kubernetes: 8# large project with many SIGsopen-telemetry: 6
Check: on issues.opened / issues.edited, count open proposal issues
with the same <CNCF Project> + <Term> labels. If count > quota, label over-quota and post a comment listing the existing proposals so the
project can decide which to withdraw.
Override: an admin can remove the over-quota label manually after
confirming the exception is intentional.
Tone: this should be a warning, not a hard block — the goal is to
surface the situation, not to litigate it via a bot.
4.3.2 Maintainer / project approval verification
Each program needs at least one approval from a maintainer of the CNCF
project, or from an equivalent project-governance role for larger projects
(e.g., a Kubernetes SIG-ContribEx lead, or an OpenTelemetry SIG/Governance
Committee liaison).
Sources of truth (checked in order):
The approvals workflow uses a four-tier authorization chain. It checks
each tier in order and stops at the first match:
.project maintainers — if the project's GitHub org has adopted the CNCF .project tooling,
the workflow fetches {org}/.project/maintainers.yaml and checks the project-maintainers team members list. This is only attempted when the
landscape sync has flagged has_dot_project: true for the project in projects.yml.
cncf/foundation/project-maintainers.csv — cncf/foundation/blob/main/project-maintainers.csv
(columns: lifecycle stage, Project, Maintainer Name, Company, Github Name,
OWNERS link). Parse rows scoped to the selected project; the Github Name
column gives us the candidate approver list.
Global approvers — also in approvers.yml. These handles can /approve for any project (useful for CNCF staff and cross-project
liaisons):
global_approvers:
- nate-double-u
- dkrook
Verification mechanism: a comment containing /approve (Prow-style)
from an authorized user. The workflow scans every line of the comment for
the command (so context text before the /approve is fine). Unauthorized
users who attempt /approve receive a reply explaining why it didn't work
and listing the recognized approver sources.
Workflow behavior:
On issue_comment.created, the workflow detects /approve and checks
the commenter against the four-tier auth chain above.
If authorized, the workflow applies the Maintainer/Contribex Approved
label and posts a confirmation comment.
If unauthorized, the workflow replies explaining that the commenter isn't
recognized as a maintainer for that project and lists the sources checked.
The proposer's own /approve is permitted if they appear in any of the
four tiers — maintainers often self-propose.
4.3.3 Mentor confirmation
Every mentor named on the proposal — primary plus any additional — needs to
confirm in writing that they're willing to mentor for this term. Today this
happens implicitly (mentor opens or co-authors the PR), or they 👍 or
approve the PR. With the issue-form flow, the proposer may not be one of
the mentors, so we need an explicit confirmation step.
Verification mechanism: a comment containing /confirm from a mentor
whose GitHub handle is listed in the Mentors field of the issue body. The
workflow parses the Mentors table to extract GitHub handles and checks the
commenter against that list.
Workflow behavior:
On issue_comment.created, the workflow detects /confirm and checks
whether the commenter's GitHub handle appears in the Mentors field.
If recognized, the workflow applies the Mentors Confirmed label and
posts a confirmation comment. (Current MVP confirms on any single
mentor's /confirm; tracking per-mentor confirmation status is a future
enhancement.)
If the commenter isn't listed as a mentor, the workflow replies explaining
why it didn't work.
Identity check: confirmation must come from the GitHub handle listed on
the form. If @alice is listed and @alice2 comments /confirm, that
doesn't count — this catches typos in the form before they propagate to LFX.
Workflow behavior:
On issues.opened and on issues.edited (when the mentor list changes),
the bot posts a comment that @-mentions every listed mentor and asks each
of them to either 👍-react on the issue or comment /confirm.
The bot tracks which mentors have confirmed. As long as one or more
confirmations are missing, the issue stays in Awaiting approvals / confirmations and the bot's tracker comment is upserted with the current
state ("✅ confirmed: @A, @b — ⏳ pending: @c").
Once all listed mentors have confirmed, apply the existing Mentors Confirmed label.
If the mentor list is later edited to add a new mentor, the Mentors Confirmed label is cleared and the bot re-pings just the new
names.
Identity check: confirmation must come from the GitHub handle listed on
the form. If @alice is listed and @alice2 reacts, that doesn't count —
this catches typos in the form before they propagate to LFX.
4.3.4 CNCF Mentorship admin approval
The final gate before a proposal moves to "CNCF Approved" is sign-off from
the CNCF Mentorship admin team.
Source of truth: the global_approvers list in programs/lfx-mentorship/automation/approvers.yml. (Current MVP; can
migrate to a GitHub team like cncf/mentorship-admins later.)
Workflow behavior:
The bot does not ping admins automatically — admin review is intentional,
not automatic. Admins find proposals via the project board's Awaiting approvals / confirmations and approved/confirmed columns.
An admin signals approval via a /cncf-approve comment.
On detection, the bot checks that both Maintainer/Contribex Approved
and Mentors Confirmed labels are present. If either is missing, it
replies with a warning explaining which gate(s) are still open, and does not apply the label.
If both gates are satisfied, the bot applies the CNCF Approved label,
which moves the issue to the CNCF Approved column on the project board
(§4.4).
Sequencing summary (all gated on validation passing):
Auto when a PR touching the term README that closes this issue merges
Open for Applications
Scheduled / manual — driven by LFX calendar
Applications Closed
Scheduled / manual
Closed
Issue closed
Setup instructions for the Project v2 token:
The board sync workflow requires a PAT stored as the PROJECT_TOKEN repo
secret. The token type differs between dev and prod because fine-grained
tokens don't yet support Projects permission for user-owned projects.
Development (nate-double-u/mentoring fork) — classic PAT
Expiration: 90 days (set a calendar reminder to rotate)
Resource owner:cncf (requires org admin approval)
Repository access: select cncf/mentoring
Permissions:
Organization → Projects: Read and write
Generate, get org admin approval if required, and store as a repo secret:
gh secret set PROJECT_TOKEN --repo cncf/mentoring
Why the difference? Fine-grained PATs don't yet expose the Projects
permission for user-owned projects (only org-owned). Classic PATs have a
broad project scope that works for both. Once GitHub adds fine-grained
support for user-owned projects, the dev setup can switch to match prod.
Long-term: migrate to a GitHub App with projects: write to avoid
PAT expiration and single-user bus factor.
4.5 Export: machine-readable artifact, human-readable README, and tracking CSV for LFX
A manual workflow_dispatch workflow walks all open issues with Proposal + CNCF Approved labels for a given term and produces three outputs:
lfx-export.json — structured JSON for the LFX platform team to
bulk-import. One record per program with all fields parsed from the issue
form (project metadata, mentors, prerequisites, etc.). The schema should
mirror the LFX bulk-import schema as closely as possible — this is the
single most important thing to confirm with LFX up front. See §4.1.1
for the field-mapping inferred from the LFX wizard UI.
Mentor identities are included in the export (parsed from the textarea
per §4.1.3, primary = first row).
For fields auto-populated from cncf/landscape (Website URL, CoC URL,
Logo, OpenSSF Best Practices ID), the export workflow looks up the
selected CNCF project at export time and injects the values.
README.md — human-readable accepted-programs list in the existing
format used by cncf/mentoring. Generated from the same issue data.
Includes:
Term header, status, duration
Table of Contents (nested: CNCF Project → program titles)
Accepted Projects section with full details per program (description
that covers both what the program is about and expected outcomes,
recommended skills, technologies, mentors, upstream issue, LFX URL
placeholder)
lfx-tracking.csv — flat CSV for importing into the program admin's
tracking spreadsheet. Columns:
Column
Notes
PROJECT
Full LFX program name (CNCF - <Project>: <Program> (<Term>))
LFX URL
Blank at export time; filled in after programs are created on LFX
Upstream issue
From the form
(empty)
Spacer column
mentor count
Number of mentors listed
Mentor 1 … Mentor 4
Name
Mentor 1 GitHub … Mentor 4 GitHub
GitHub handle
Mentor 1 email address … Mentor 4 email address
Email
Up to 4 mentors per program (flattened into columns). Programs with
fewer mentors leave the extra columns blank.
Both files are written to programs/lfx-mentorship/<year>/<term>/ and the
workflow opens a PR for review.
Issue notifications: After generating the export files, the workflow:
Adds the Exported label to each included issue
Comments on each issue with a link to the export files on the PR branch
This keeps mentors and maintainers informed without requiring them to
watch the repo's Actions tab.
Stretch: replace the export PR with a direct API call to LFX
(POST /programs) once such an endpoint exists. The intermediate file is
still useful as an audit trail.
LFX programs can attach per-program prerequisite tasks with a name, due date,
description, and an optional "requires file upload" flag. LFX provides a standard prerequisite library (Resume, Cover Letter, School Enrollment
Verification, Participation Permission from school/employer, Coding Challenge),
each toggle-able and with an editable description. Custom Prerequisites can
also be added — name capped at 20 chars, description at 500 chars (these limits
are tight; see §6 ask).
CNCF currently applies at least one custom prerequisite uniformly across all
programs in a term:
Prerequisite name: Inclusive Community Due date: ~2 weeks after program start (e.g. 2026-05-19 for Term 2) Description: Upload completion certificate for Inclusive Open Source Community Orientation (LFC102). Certificate is found in the mentee's openprofile.dev dashboard under Training & Certifications → Certificates of Completion. Requires file upload: ✓ Yes
Today this is configured by hand on each program in the LFX admin UI, and verified
by hand by the program admin checking that an uploaded PDF matches what LFC102
issues. Two integration opportunities:
4.6a. Bulk-set prerequisites in the export schema (§4.5).
Whatever schema we agree with the LFX team should include a prerequisites: [...]
block per program (or a "default prerequisites" table at the term level), so the
Inclusive Community task is set automatically on every imported program.
4.6b. Distinct from application requirements. Prerequisites (this section)
are tasks the mentee completes after selection, with due dates. Application
requirements (§4.7) are things applicants submit during application, before
selection — writing samples, project proposals, etc. The two are configured
separately on LFX and serve different purposes.
4.6c. LF Education integration (stretch).
LFC102 is issued by LF Training & Certification (training.linuxfoundation.org)
and surfaces on openprofile.dev. If the LFX team can wire LFX ↔ LF Education
to check completion programmatically — keyed on the mentee's LFID — we can drop
the manual certificate-PDF review entirely. This is the LF-Education-side ask
worth coordinating with the LFX team on.
This affects only the LFX-side ask list (see "Asks of LFX" → ask #6 below); no
change to the intake issue form is needed in v1, since maintainers don't author
this field.
4.7 Per-program application requirements
Unlike prerequisites (§4.6a, term-wide and uniform), application requirements
are configured per program by the maintainer to filter / evaluate applicants before selection. The most common patterns surfaced so far:
Writing sample (file upload) — common for technical-writing programs.
Project proposal (file upload or long-text) — some mentors want
applicants to articulate how they'd approach the work before being selected.
Code sample or portfolio link — common for senior-skewing programs.
All application requirements are treated as required (hard gate;
applicant cannot submit without satisfying them). We deliberately do not offer
an "optional" variant: if it's optional, it isn't a requirement, and offering
the choice multiplies administrative overhead without changing outcomes.
Mapping to LFX standard prerequisites:
LFX provides built-in toggle-able application items (see §4.6 / screenshots).
Our form's checkboxes should map to those rather than create parallel custom
prerequisites where a standard one already exists:
Our checkbox
LFX equivalent
Notes
Project proposal (file upload)
Standard: Cover Letter
LFX's Cover Letter has a built-in structured prompt (motivation, experience, goals). Customize the prompt at export time if needed.
Code sample or portfolio link
Standard: Coding Challenge
URL-based; works for portfolio links too.
Writing sample (file upload)
Custom Prerequisite
No LFX standard for this. Add as a Custom Prerequisite with name "Writing Sample" and "requires file upload" flag set.
Other / describe below
Custom Prerequisite
Manually configured.
Form treatment: structured checkboxes (one per common pattern) plus an
"Other / describe below" textarea escape hatch for items that don't fit the
common patterns. The textarea is also treated as describing required items.
Export treatment: the export schema (§4.5) should set the corresponding
LFX standard prerequisite toggles where they exist, and emit a Custom
Prerequisite block where they don't. All entries are implicitly required.
LFX-side ask: confirm that the bulk-import schema can set application
questions per program (it almost certainly can, since the admin UI does — but
worth verifying before we design the form fields to match). See "Asks of LFX"
ask #2.
4.8 Human-readable view
Today's project_ideas.md is replaced by the auto-generated README.md
from §4.5. There is no separate "proposed ideas" file in the new flow — the
issue form is the proposal, and the exported README is the accepted-programs
list.
Source of truth is the issues; the markdown file is a convenience index.
README.md is generated by the export workflow (§4.5), not hand-edited.
The Description field in the README covers both what the program is about
and expected outcomes (merged into a single "Program Description" in the
issue form, matching the LFX platform's single description field).
5. Asks of LFX (in priority order)
These determine how much of the above we can actually automate.
LFID/email lookup endpoint. GET https://api.../v1/users?email=... returning { lfid, verified, accepted_tos } or 404. Why first: this single endpoint eliminates the most common day-of-launch failure (mentor email mismatch) and is the most user-visible win.
Documented bulk-import schema for programs.
CSV or JSON, with field names, character/byte limits (see §4.1.1 for our
reverse-engineered field map and pain points like the 100-char Program Name
and 20-char Custom Prerequisite Name), required/optional, enum values for
term / standard prerequisites. Must include support for per-program
prerequisites (§4.6a, both standard-toggles and custom slots) and
confirmation that the standard prerequisites (Resume, Cover Letter, etc.)
can be enabled via the import. Even without an API, this lets us generate
exactly the file you need.
Project-create / program-create API. POST /programs accepting the schema from (2). Lets us skip the manual upload entirely.
Test/staging environment for the above. The validation workflow shouldn't hit prod LFX on every issue edit.
Webhooks for state changes (program.approved, mentor.added, applications.opened, applications.closed). Lets us drop the manual Status flips on the project board.
LF Education integration for prerequisite verification.
The LFC102 ("Inclusive Open Source Community Orientation") certificate is
currently uploaded as a PDF by mentees and verified by hand. If LFX can
query LF Education / openprofile.dev for course completion status keyed on
LFID, we can mark the prerequisite complete automatically. This likely
requires LFX-team coordination with LF Training & Certification rather than
something they own end-to-end. See §4.6 for context.
Field-level confirmations from the LFX wizard. Specifically:
Confirm: are "Technologies" (Program Details) and "Required and/or desirable skills and training" (Program Setup) two genuinely independent fields on the back end, or one field rendered twice? Our form treats them as independent with a "same as Technologies" shortcut (§4.1.4); if they're actually the same field on the LFX side, we can simplify.
Can the Custom Prerequisite Name limit (20 chars, currently breaking on "Inclusive Community" at 19/20) and Description limit (500 chars) be raised?
Can the Program Name limit (100 chars) be raised, given common naming conventions consume ~16 chars on the term suffix alone?
Operational asks (not strictly LFX)
Service token / API key, with documented rate limits and rotation policy.
Confirmation that it's OK to comment on a public issue with the result of "email X is/is-not registered on LFX" — or whether we should keep that to a private signal.
6. Open questions
Approval expression mechanism. §4.3.2 leans toward 👍 reactions or /approve comments from candidate approvers. Other valid options: require
a comment containing the literal word "approve" (looser, more false
positives), or open a parallel PR for each issue and use PR review-approve
(heavier). 👍//approve feels like the right balance, but worth socializing.
Quota enforcement vs. warning. §4.3.1 treats over-quota as a warning,
not a hard block. If project admins want a hard block, the workflow can
refuse to advance the issue past Inbox until the count is back in range.
ContribEx-equivalent registry maintenance. The programs/lfx-mentorship/approvers.yml overrides file (§4.3.2) needs to
be kept current. Recommend treating it like CODEOWNERS — a small admin
task, edited via PR, reviewed by program admin and the affected project's
liaison.
Multi-term programs. LFX models a single program as hosting multiple
terms (you Add Term to an existing program rather than creating a new
program each term — see §4.1.1). CNCF currently treats each term as a fresh
unit (per-term project_ideas.md, separate project board per term). Worth
deciding whether to align with LFX's model — would meaningfully reduce
per-term setup effort but changes the lifecycle picture.
Program-specific extra prerequisites. Some projects may want to attach
their own prerequisite tasks beyond the term-wide Inclusive Community
requirement (e.g. "complete project X's onboarding tutorial"). Recommend not adding this to the v1 issue form — keep the form tight, handle extras
as a follow-up issue comment that the admin configures manually in LFX. If
this becomes common, add an optional textarea field in v2.
Application-requirement enumeration. v1 form covers writing sample /
project proposal / code sample, all treated as required. If maintainers
routinely ask for things outside that set (e.g. specific assessments,
language proficiency proofs), promote them from the "Other" textarea to
first-class checkboxes in v2. Worth reviewing after one term.
File-upload destination. LFX's application form handles applicant file
uploads natively. Confirm with LFX that uploaded writing samples / proposals
remain accessible to mentors and to the program admin during selection
(and what the retention policy is post-selection).
One issue per program vs. one issue per maintainer batch. Recommend per-program for lifecycle clarity, but maintainers proposing many programs may push back. Mitigate with a gh-based CLI helper or a "duplicate this issue" link in the bot comment.
Migration of in-flight terms. Don't migrate 2026 Term 2 mid-flight; cut over for 2026 Term 3 or 2027 Term 1.
GSoC reuse. GSoC has its own template (PROJECT_IDEA_TEMPLATE.md) with subtly different fields (e.g. requires ≥2 mentors). Worth deciding whether GSoC gets its own form, or one form with a "program type" dropdown.
Notification fatigue. Every issue edit re-runs validation and may re-comment. Mitigate by upserting the comment (one comment per issue, edited in place) and only re-validating on edits to the relevant fields.
Spam / abuse. Public issue forms invite drive-by submissions. The required-approval gates (§4.3.2) act as the real spam filter — no proposal moves past Awaiting Maintainer/Contribex Approval without a 👍 / /approve from a known project maintainer or fallback approver. Admin triage on Inbox catches the rest. May want CODEOWNERS-style auto-assign of admin reviewers.
7. Risks & mitigations
Risk
Mitigation
LFX team can't / won't expose APIs
All format checks still work; admin still has to manually verify mentor LFIDs (status quo, but with structured input — still a win)
Maintainers prefer the PR flow ("muscle memory")
Keep PRs working as fallback for one term; deprecate after one full cycle
Bot comments get noisy on edited issues
Upsert single comment; debounce on field-level diff
Share with 1–2 friendly maintainers who've filed multiple proposals across terms, for form-field sanity check.
Refine the form and decide which automations to build before the next term cutover.
Pick a cutover term (recommend 2026 Term 3 or 2027 Term 1; not mid-Term-2).
Decide on Project v2 token strategy: fine-grained PAT vs. GitHub App.
Don't merge anything to cncf/mentoring yet — this is a discussion artifact, not a proposal to ship.
10. How to give feedback
👍 / 👎 reactions on this issue if you broadly support / oppose the direction.
Comment with your role (maintainer / mentor / LFX team / admin) and any specific concerns. If your feedback targets one section, please reference the section number (e.g. "re §4.7 application requirements: …").
For LFX platform team: I'd love a steer on §5 asks — even an early "this one's feasible / this one isn't" is hugely valuable for prioritizing the build.
For maintainers / mentors: thoughts on whether the form fields in §4.1 capture what you'd actually want to express, and whether the application-requirement defaults in §4.7 match the patterns you use.
TL;DR
Replace today's "open a PR against
project_ideas.md" intake with a GitHub Issue Form + a small set of GitHub Actions workflows that:This issue is a discussion document. Feedback welcome from maintainers, mentors, the LFX Mentorship platform team, and CNCF program admins. See §10 How to give feedback at the bottom.
Authored by @nate-double-u with assistance from Copilot CLI.
1. Problem
The current intake process for each LFX Mentorship term requires maintainers and prospective mentors to open pull requests against
programs/lfx-mentorship/<year>/<term>/project_ideas.md, adding a free-form markdown block per program. This is painful in three ways:2. Goals
3. Non-goals
4. Proposed approach
4.1 Intake: GitHub Issue Form
A new
.github/ISSUE_TEMPLATE/lfx-program-proposal.ymlform replaces thenear-empty existing template. Each submitted issue represents one program proposal.
Fields (subject to refinement once LFX import schema is known):
cncf/landscape. See §4.2.2026 Term 1); months shown as helper text.Full Name | @github-handle | lfid-email. The first line is the primary mentor; subsequent lines are additional mentors. See §4.1.3 for rationale and validation.Auto-applied labels on submission:
lfx mentorship,proposal,needs-validation.Why one issue per program (not one issue per maintainer with multiple programs):
The project-board lifecycle is per-program. Bundling forces multiple programs into one row and re-creates today's mismatch.
4.1.1 Mapping to the LFX platform wizard
The form fields above are designed to populate LFX's program-creation wizard
(see screenshots attached to this issue). Important constraints learned from
the LFX UI:
CNCF - <Project name>: <program name> (<term>).cncf/landscapefor the selected project. If landscape is missing the value, fix it upstream (incncf/landscape) — don't add a manual-override field on our form.cncf/landscapefor the selected project. If landscape doesn't have one, default to the CNCF Code of Conduct — every CNCF project is bound by it regardless.These are valuable for our own intake and project-board tracking, and the mentor list also seeds LFX's post-approval Mentors tab.
4.1.2 Program Name composition
CNCF programs follow a strict naming convention on LFX:
Example:
CNCF - LitmusChaos: Add Prometheus Metrics to Control Plane Service (2026 Term 1)The fixed scaffolding consumes 23 characters plus the project name (and term):
CNCF -(7):(2)(+)around the term (3)<term>itself (e.g.2026 Term 1= 11)So for the typical
<term>value ofYYYY Term N(11 chars), the availablebudget for the bare program name depends on the project name length:
Form treatment: the issue form collects only the bare middle in the
"Program Name" field. The CNCF Project (§4.2 dropdown) and Term (§4.1
dropdown) supply the surrounding pieces. The export workflow (§4.5)
composes the full LFX Program Name value at export time. The validation
workflow (§4.3) checks that the bare program name fits within the budget for
the selected project and warns the author with a precise character count if
not. This both prevents truncation (as seen in the screenshot, where 98/100
chars chopped the front of "Native Support for AI Agent...") and eliminates
the naming-convention drift visible across recent PRs (
Term 1vsT1,missing year, missing "CNCF -" prefix, etc.).
The Term dropdown values (§4.1) should produce just the
<term>tokenexpected by the convention (e.g.
2026 Term 1), not a longer label includingmonths. If you want the months visible to the form author, render them as
helper text below the dropdown rather than as part of the option string.
4.1.3 Mentors field shape
We need three things per mentor: full name, GitHub handle, and the
email address tied to their LFID (transitional — once we can look up LFIDs
directly, the email column becomes the LFID).
GitHub Issue Forms don't support repeating field groups, so a variable-length
list of structured records has to live in a single textarea. We use one line
per mentor with a pipe-separated format:
Example:
The first line is the primary mentor; subsequent lines are additional
mentors. There is exactly one form field for both — no separate "Primary
Mentor" block — which keeps the data shape consistent across mentor counts
and avoids the awkward "why does the primary mentor get three fields but the
additional mentors only get a textarea" inconsistency.
Why pipe-separated, not comma-separated: names contain commas
("Smith, John, PhD"); pipes don't appear in real names, GitHub handles, or
emails, so parsing is unambiguous.
Validation rules (also reflected in §4.3):
@[A-Za-z0-9-]{1,39}(GitHub handle rules)4.1.4 Technologies vs. Required/Desirable Skills
The LFX wizard exposes two chip-style fields that look similar but live in
different wizard steps (see screenshots, §4.1.1):
the program — languages, frameworks, platforms.
what an applicant should know coming in.
In the common case these are the same set ("if the program is in Go on
Kubernetes, applicants need Go and Kubernetes"). In the less-common case
they diverge — e.g. a documentation program might be about a particular
codebase (Technologies = the project's language/stack) but only require
prose skills of the applicant (Skills = "technical writing, Markdown").
We collect both fields so we can populate the LFX wizard accurately, but
add a single checkbox "Skills same as Technologies?" (default checked)
so the proposer doesn't retype the same set in 90% of cases. Form behavior:
Technologies for both wizard fields
warns about the contradiction (likely user error); admin clarifies
("either check the box or fill in the field")
field as given
Issue Forms can't conditionally show/hide fields, so both inputs are always
visible; the checkbox is a signal the workflow reads at validation and
export time, not a UX trigger.
4.1.5 Program Description prompt
LFX has one combined Program Description field (3000 chars). Mentors vary
on how they'd want to split that — some lead with outcomes, some with
context, some weave them together. Rather than impose a structure, we
collect a single field but use the form's placeholder/sample text to
prompt for both halves so nothing important gets dropped:
The
placeholdertext appears greyed-out inside the textarea until theproposer starts typing — so it shows the suggested structure without
forcing it. The
description(above the textarea) gives the rules.Validation enforces the 3000-char hard limit (§4.3) but doesn't enforce the
structure — proposers can use the suggested headings, their own headings,
or none at all.
4.2 CNCF Project dropdown — keeping it current
GitHub Issue Form dropdowns are static — options are baked into the form's
YAML at commit time, not fetched at issue-creation time. To keep the CNCF
Project dropdown in sync with reality without manual edits, a scheduled
workflow regenerates the form's
options:block from the canonical landscapedata.
Source:
landscape.ymlincncf/landscape.Filter to category
CNCF Graduated, Incubating, and Sandbox(i.e., activeCNCF-hosted projects), excluding archived projects and the many landscape
entries that are not CNCF-hosted (member companies, end-user companies, etc.).
That yields ~200 projects, well within issue-form dropdown limits.
Workflow shape:
workflow_dispatchfor ad-hoc refresh.landscape.yml→ filter → diff against current options block inlfx-program-proposal.yml→ if changed, rewrite the YAML and open a PR (or auto-commit, if low-risk).Assisted-by:trailer per CNCF convention.Edge cases:
sigs.k8s.io/node-readiness-controllerproposal. The dropdown should include an explicitOther / not yet listedoption that reveals (via the validation workflow's bot comment) a freeform follow-up where the proposer explains. Avoids forcing edge cases through an overly-narrow dropdown.name:field as-is so naming flows downstream consistently. (Examples in recent PRs include bothkgatewayandKgateway— pick the landscape spelling and stick to it.)4.3 Validation: GitHub Actions workflow
.github/workflows/lfx-proposal-validate.ymltriggers onissues.opened/issues.editedfor issues carrying thelfx mentorship+proposallabels.It performs:
Format checks (immediate, no external deps):
LFX checks (stretch — requires LFX cooperation; see "Asks of LFX" below):
CNCF checks (no external dependencies; details in §4.3.1–§4.3.4):
Output:
validation-passed/validation-failed.needs-validationremoved once a verdict exists.Implementation note (security):
A draft of the validation workflow uses
peter-murray/issue-forms-body-parser@v4.1.0for body parsing. Recommend inlining the parser (~30 lines insideactions/github-script) for the production version to avoid a third-party supply-chain dependency in a workflow that will hold theLFX_API_TOKENsecret. If we keep the third-party action, pin to a full commit SHA, not a tag.4.3.1 Per-project per-term proposal quota
CNCF projects are currently capped at 4–5 program proposals per term
(subject to change in future terms). Today this is enforced by program-admin
attention; we can move it into validation:
programs/lfx-mentorship/quotas.ymlwith a global default and per-projectoverrides:
issues.opened/issues.edited, count open proposal issueswith the same
<CNCF Project>+<Term>labels. Ifcount > quota, labelover-quotaand post a comment listing the existing proposals so theproject can decide which to withdraw.
over-quotalabel manually afterconfirming the exception is intentional.
surface the situation, not to litigate it via a bot.
4.3.2 Maintainer / project approval verification
Each program needs at least one approval from a maintainer of the CNCF
project, or from an equivalent project-governance role for larger projects
(e.g., a Kubernetes SIG-ContribEx lead, or an OpenTelemetry SIG/Governance
Committee liaison).
Sources of truth (checked in order):
The approvals workflow uses a four-tier authorization chain. It checks
each tier in order and stops at the first match:
.projectmaintainers — if the project's GitHub org has adopted theCNCF
.projecttooling,the workflow fetches
{org}/.project/maintainers.yamland checks theproject-maintainersteam members list. This is only attempted when thelandscape sync has flagged
has_dot_project: truefor the project inprojects.yml.cncf/foundation/project-maintainers.csv—cncf/foundation/blob/main/project-maintainers.csv(columns: lifecycle stage, Project, Maintainer Name, Company, Github Name,
OWNERS link). Parse rows scoped to the selected project; the
Github Namecolumn gives us the candidate approver list.
Per-project fallbacks —
programs/lfx-mentorship/automation/approvers.yml:Global approvers — also in
approvers.yml. These handles can/approvefor any project (useful for CNCF staff and cross-projectliaisons):
Verification mechanism: a comment containing
/approve(Prow-style)from an authorized user. The workflow scans every line of the comment for
the command (so context text before the
/approveis fine). Unauthorizedusers who attempt
/approvereceive a reply explaining why it didn't workand listing the recognized approver sources.
Workflow behavior:
issue_comment.created, the workflow detects/approveand checksthe commenter against the four-tier auth chain above.
Maintainer/Contribex Approvedlabel and posts a confirmation comment.
recognized as a maintainer for that project and lists the sources checked.
/approveis permitted if they appear in any of thefour tiers — maintainers often self-propose.
4.3.3 Mentor confirmation
Every mentor named on the proposal — primary plus any additional — needs to
confirm in writing that they're willing to mentor for this term. Today this
happens implicitly (mentor opens or co-authors the PR), or they 👍 or
approve the PR. With the issue-form flow, the proposer may not be one of
the mentors, so we need an explicit confirmation step.
Verification mechanism: a comment containing
/confirmfrom a mentorwhose GitHub handle is listed in the Mentors field of the issue body. The
workflow parses the Mentors table to extract GitHub handles and checks the
commenter against that list.
Workflow behavior:
issue_comment.created, the workflow detects/confirmand checkswhether the commenter's GitHub handle appears in the Mentors field.
Mentors Confirmedlabel andposts a confirmation comment. (Current MVP confirms on any single
mentor's
/confirm; tracking per-mentor confirmation status is a futureenhancement.)
why it didn't work.
Identity check: confirmation must come from the GitHub handle listed on
the form. If
@aliceis listed and@alice2comments/confirm, thatdoesn't count — this catches typos in the form before they propagate to LFX.
Workflow behavior:
issues.openedand onissues.edited(when the mentor list changes),the bot posts a comment that @-mentions every listed mentor and asks each
of them to either 👍-react on the issue or comment
/confirm.confirmations are missing, the issue stays in
Awaiting approvals / confirmationsand the bot's tracker comment is upserted with the currentstate ("✅ confirmed: @A, @b — ⏳ pending: @c").
Mentors Confirmedlabel.Mentors Confirmedlabel is cleared and the bot re-pings just the newnames.
Identity check: confirmation must come from the GitHub handle listed on
the form. If
@aliceis listed and@alice2reacts, that doesn't count —this catches typos in the form before they propagate to LFX.
4.3.4 CNCF Mentorship admin approval
The final gate before a proposal moves to "CNCF Approved" is sign-off from
the CNCF Mentorship admin team.
Source of truth: the
global_approverslist inprograms/lfx-mentorship/automation/approvers.yml. (Current MVP; canmigrate to a GitHub team like
cncf/mentorship-adminslater.)Workflow behavior:
not automatic. Admins find proposals via the project board's
Awaiting approvals / confirmationsandapproved/confirmedcolumns./cncf-approvecomment.Maintainer/Contribex Approvedand
Mentors Confirmedlabels are present. If either is missing, itreplies with a warning explaining which gate(s) are still open, and does
not apply the label.
CNCF Approvedlabel,which moves the issue to the
CNCF Approvedcolumn on the project board(§4.4).
Sequencing summary (all gated on validation passing):
Awaiting Maintainer/Contribex Approval+Awaiting Mentor Confirmation/approvecomment (§4.3.2)Maintainer/Contribex Approved/confirmcomment (§4.3.3)Mentors Confirmed/cncf-approvecomment (§4.3.4)CNCF Approved4.4 Lifecycle: Project board automation
A second workflow keeps Project #92 (and successor boards each term) in sync
with the issue's state, mirroring today's manual flow:
issues.openedwithproposallabel → add to project, set Statusvalidation-passedset, butMaintainer/Contribex Approvedand/orMentors Confirmedmissing (§4.3.2, §4.3.3)Maintainer/Contribex ApprovedandMentors Confirmedpresentcncf-approvedlabel applied via §4.3.4Exportedlabel + comments on each issue linking to the export filesSetup instructions for the Project v2 token:
The board sync workflow requires a PAT stored as the
PROJECT_TOKENreposecret. The token type differs between dev and prod because fine-grained
tokens don't yet support Projects permission for user-owned projects.
Development (nate-double-u/mentoring fork) — classic PAT
MENTORING_PROJECT_BOARD_DEVproject(Full control of projects)gh secret set PROJECT_TOKEN --repo nate-double-u/mentoringProduction (cncf/mentoring) — fine-grained PAT
MENTORING_PROJECT_BOARD_PRODcncf(requires org admin approval)cncf/mentoringgh secret set PROJECT_TOKEN --repo cncf/mentoring4.5 Export: machine-readable artifact, human-readable README, and tracking CSV for LFX
A manual
workflow_dispatchworkflow walks all open issues withProposal+CNCF Approvedlabels for a given term and produces three outputs:lfx-export.json— structured JSON for the LFX platform team tobulk-import. One record per program with all fields parsed from the issue
form (project metadata, mentors, prerequisites, etc.). The schema should
mirror the LFX bulk-import schema as closely as possible — this is the
single most important thing to confirm with LFX up front. See §4.1.1
for the field-mapping inferred from the LFX wizard UI.
per §4.1.3, primary = first row).
cncf/landscape(Website URL, CoC URL,Logo, OpenSSF Best Practices ID), the export workflow looks up the
selected CNCF project at export time and injects the values.
README.md— human-readable accepted-programs list in the existingformat used by
cncf/mentoring. Generated from the same issue data.Includes:
that covers both what the program is about and expected outcomes,
recommended skills, technologies, mentors, upstream issue, LFX URL
placeholder)
lfx-tracking.csv— flat CSV for importing into the program admin'stracking spreadsheet. Columns:
PROJECTCNCF - <Project>: <Program> (<Term>))LFX URLUpstream issuementor countMentor 1…Mentor 4Mentor 1 GitHub…Mentor 4 GitHubMentor 1 email address…Mentor 4 email addressUp to 4 mentors per program (flattened into columns). Programs with
fewer mentors leave the extra columns blank.
Both files are written to
programs/lfx-mentorship/<year>/<term>/and theworkflow opens a PR for review.
Issue notifications: After generating the export files, the workflow:
Exportedlabel to each included issueThis keeps mentors and maintainers informed without requiring them to
watch the repo's Actions tab.
Stretch: replace the export PR with a direct API call to LFX
(
POST /programs) once such an endpoint exists. The intermediate file isstill useful as an audit trail.
4.6 Mentee prerequisites & LF Education integration
LFX programs can attach per-program prerequisite tasks with a name, due date,
description, and an optional "requires file upload" flag. LFX provides a
standard prerequisite library (Resume, Cover Letter, School Enrollment
Verification, Participation Permission from school/employer, Coding Challenge),
each toggle-able and with an editable description. Custom Prerequisites can
also be added — name capped at 20 chars, description at 500 chars (these limits
are tight; see §6 ask).
CNCF currently applies at least one custom prerequisite uniformly across all
programs in a term:
Today this is configured by hand on each program in the LFX admin UI, and verified
by hand by the program admin checking that an uploaded PDF matches what LFC102
issues. Two integration opportunities:
4.6a. Bulk-set prerequisites in the export schema (§4.5).
Whatever schema we agree with the LFX team should include a
prerequisites: [...]block per program (or a "default prerequisites" table at the term level), so the
Inclusive Community task is set automatically on every imported program.
4.6b. Distinct from application requirements. Prerequisites (this section)
are tasks the mentee completes after selection, with due dates. Application
requirements (§4.7) are things applicants submit during application, before
selection — writing samples, project proposals, etc. The two are configured
separately on LFX and serve different purposes.
4.6c. LF Education integration (stretch).
LFC102 is issued by LF Training & Certification (training.linuxfoundation.org)
and surfaces on openprofile.dev. If the LFX team can wire LFX ↔ LF Education
to check completion programmatically — keyed on the mentee's LFID — we can drop
the manual certificate-PDF review entirely. This is the LF-Education-side ask
worth coordinating with the LFX team on.
This affects only the LFX-side ask list (see "Asks of LFX" → ask #6 below); no
change to the intake issue form is needed in v1, since maintainers don't author
this field.
4.7 Per-program application requirements
Unlike prerequisites (§4.6a, term-wide and uniform), application requirements
are configured per program by the maintainer to filter / evaluate applicants
before selection. The most common patterns surfaced so far:
applicants to articulate how they'd approach the work before being selected.
All application requirements are treated as required (hard gate;
applicant cannot submit without satisfying them). We deliberately do not offer
an "optional" variant: if it's optional, it isn't a requirement, and offering
the choice multiplies administrative overhead without changing outcomes.
Mapping to LFX standard prerequisites:
LFX provides built-in toggle-able application items (see §4.6 / screenshots).
Our form's checkboxes should map to those rather than create parallel custom
prerequisites where a standard one already exists:
Form treatment: structured checkboxes (one per common pattern) plus an
"Other / describe below" textarea escape hatch for items that don't fit the
common patterns. The textarea is also treated as describing required items.
Export treatment: the export schema (§4.5) should set the corresponding
LFX standard prerequisite toggles where they exist, and emit a Custom
Prerequisite block where they don't. All entries are implicitly required.
LFX-side ask: confirm that the bulk-import schema can set application
questions per program (it almost certainly can, since the admin UI does — but
worth verifying before we design the form fields to match). See "Asks of LFX"
ask #2.
4.8 Human-readable view
Today's
project_ideas.mdis replaced by the auto-generatedREADME.mdfrom §4.5. There is no separate "proposed ideas" file in the new flow — the
issue form is the proposal, and the exported README is the accepted-programs
list.
README.mdis generated by the export workflow (§4.5), not hand-edited.and expected outcomes (merged into a single "Program Description" in the
issue form, matching the LFX platform's single description field).
5. Asks of LFX (in priority order)
These determine how much of the above we can actually automate.
LFID/email lookup endpoint.
GET https://api.../v1/users?email=...returning{ lfid, verified, accepted_tos }or 404.Why first: this single endpoint eliminates the most common day-of-launch failure (mentor email mismatch) and is the most user-visible win.
Documented bulk-import schema for programs.
CSV or JSON, with field names, character/byte limits (see §4.1.1 for our
reverse-engineered field map and pain points like the 100-char Program Name
and 20-char Custom Prerequisite Name), required/optional, enum values for
term / standard prerequisites. Must include support for per-program
prerequisites (§4.6a, both standard-toggles and custom slots) and
confirmation that the standard prerequisites (Resume, Cover Letter, etc.)
can be enabled via the import. Even without an API, this lets us generate
exactly the file you need.
Project-create / program-create API.
POST /programsaccepting the schema from (2). Lets us skip the manual upload entirely.Test/staging environment for the above. The validation workflow shouldn't hit prod LFX on every issue edit.
Webhooks for state changes (
program.approved,mentor.added,applications.opened,applications.closed). Lets us drop the manual Status flips on the project board.LF Education integration for prerequisite verification.
The LFC102 ("Inclusive Open Source Community Orientation") certificate is
currently uploaded as a PDF by mentees and verified by hand. If LFX can
query LF Education / openprofile.dev for course completion status keyed on
LFID, we can mark the prerequisite complete automatically. This likely
requires LFX-team coordination with LF Training & Certification rather than
something they own end-to-end. See §4.6 for context.
Field-level confirmations from the LFX wizard. Specifically:
Operational asks (not strictly LFX)
6. Open questions
/approvecomments from candidate approvers. Other valid options: requirea comment containing the literal word "approve" (looser, more false
positives), or open a parallel PR for each issue and use PR review-approve
(heavier). 👍/
/approvefeels like the right balance, but worth socializing.not a hard block. If project admins want a hard block, the workflow can
refuse to advance the issue past
Inboxuntil the count is back in range.programs/lfx-mentorship/approvers.ymloverrides file (§4.3.2) needs tobe kept current. Recommend treating it like CODEOWNERS — a small admin
task, edited via PR, reviewed by program admin and the affected project's
liaison.
terms (you
Add Termto an existing program rather than creating a newprogram each term — see §4.1.1). CNCF currently treats each term as a fresh
unit (per-term
project_ideas.md, separate project board per term). Worthdeciding whether to align with LFX's model — would meaningfully reduce
per-term setup effort but changes the lifecycle picture.
their own prerequisite tasks beyond the term-wide Inclusive Community
requirement (e.g. "complete project X's onboarding tutorial"). Recommend
not adding this to the v1 issue form — keep the form tight, handle extras
as a follow-up issue comment that the admin configures manually in LFX. If
this becomes common, add an optional textarea field in v2.
project proposal / code sample, all treated as required. If maintainers
routinely ask for things outside that set (e.g. specific assessments,
language proficiency proofs), promote them from the "Other" textarea to
first-class checkboxes in v2. Worth reviewing after one term.
uploads natively. Confirm with LFX that uploaded writing samples / proposals
remain accessible to mentors and to the program admin during selection
(and what the retention policy is post-selection).
gh-based CLI helper or a "duplicate this issue" link in the bot comment.PROJECT_IDEA_TEMPLATE.md) with subtly different fields (e.g. requires ≥2 mentors). Worth deciding whether GSoC gets its own form, or one form with a "program type" dropdown.Awaiting Maintainer/Contribex Approvalwithout a 👍 //approvefrom a known project maintainer or fallback approver. Admin triage onInboxcatches the rest. May want CODEOWNERS-style auto-assign of admin reviewers.7. Risks & mitigations
programs/lfx-mentorship/quotas.yml, §4.3.1)programs/lfx-mentorship/approvers.yml, §4.3.2;admins.yml, §4.3.4)dependabot-style update§8 — Update implementation status
Replace the checklist with:
lfx-program-proposal.yml) — §4.1landscape-projects-sync.yml) — §4.2, includes.projectdetectionlfx-proposal-validate.yml) — §4.3 (format checks, label management, tracker comment)lfx-proposal-approvals.yml) — §4.3.2–4.3.4 (/approve,/confirm,/cncf-approveslash commands with four-tier auth)approvers.yml,projects.yml, label configlfx-export.yml) — §4.5 (generateslfx-export.json,README.md, andlfx-tracking.csv)terms.yml, synced to issue form + export workflow by landscape synclfx-proposal-board-sync.yml) — §4.4 (labels → Project v2 Status field, inline sync in validation + approvals workflows)9. Recommended next steps
Don't merge anything to
cncf/mentoringyet — this is a discussion artifact, not a proposal to ship.10. How to give feedback