Add open source project intake system (supersedes #4)#6
Open
michaeloboyle wants to merge 118 commits into
Open
Add open source project intake system (supersedes #4)#6michaeloboyle wants to merge 118 commits into
michaeloboyle wants to merge 118 commits into
Conversation
Add GitHub issue template for project submissions, 6 workflows for the full intake lifecycle (triage, scoring, escalation vote, validation vote, approval registration, retraction), scoring template, label setup script, and approved projects registry. Implements the process defined in the Open Source Committee governance doc. Co-Authored-By: Claude Opus 4.6 <[email protected]>
…lows Co-Authored-By: Claude Opus 4.6 <[email protected]>
…utput Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
Co-Authored-By: Claude Opus 4.6 <[email protected]>
…ct voting Co-Authored-By: Claude Opus 4.6 <[email protected]>
…gex, harden script - SEC-013: Add bot filtering to validation-vote.yml vote tallying - SEC-012: Exclude issue author from voting in validation-vote.yml - SEC-014: Add repo format validation and confirmation prompt to setup-labels.sh Note: escalation-vote.yml and retraction.yml fixes were applied in prior commits. Co-Authored-By: Claude Opus 4.6 <[email protected]>
RFC-001 proposes an intelligent governance agent for the Agentics Foundation Open Source Committee. The agent perceives submissions, relates them to precedent, prepares case briefs for the committee, and records decisions. Humans hold all decision authority. Deliverables: - RFC-001-governance-agent.md: the proposal - 5 Gherkin feature files (98 scenarios, all RED): eligibility, scoring, voting, retraction, and the 4 GDoc scored examples - spec/constitution.yaml: complete GDoc encoding (every element traceable via gdoc_ref) - spec/retraction.yaml: retraction lifecycle spec - data/rvf/: seed graph (with CoI detection path), embeddings, attestation - .github/workflows/governance-agent.yml: intelligence layer workflow Co-Authored-By: Claude Opus 4.6 <[email protected]>
… scripts Local test infrastructure (82 tests, all passing): - lib/state-machine.js: 14-state governance engine with guard evaluation - lib/rvf.js: graph BFS for CoI detection, embedding similarity, attestation - lib/commands.js: slash command parser (/score, /vote, /coi, /override) - test/state-machine.test.js: 33 tests covering all paths and guards - test/rvf.test.js: 20 tests including CoI path verification - test/commands.test.js: 29 tests for command parsing and validation Fork simulation scripts: - simulate-submission.sh: create test issues for 4 GDoc scenarios - simulate-scoring.sh: post /score comments - simulate-voting.sh: post /vote comments - simulate-full-lifecycle.sh: end-to-end simulation - simulate-cleanup.sh: close test issues - verify-workflows.sh: validate workflow YAML syntax Co-Authored-By: Claude Opus 4.6 <[email protected]>
Multiple case-brief jobs running simultaneously caused merge conflicts on the attestation.jsonl append-only log. Added a 3-attempt retry loop that resolves conflicts by accepting both versions (since JSONL is append-only, all entries are valid). Co-Authored-By: Claude Opus 4.6 <[email protected]>
The 60-second rate limit window was too aggressive, causing /status and /coi responses to be suppressed when posted shortly after a /score command (which triggers the scoring workflow's bot comment). Reduced to 10 seconds, which still prevents duplicate bot tallies from concurrent workflow re-triggers while allowing distinct commands to respond. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Ran 4 simulated submissions through the full governance pipeline on the fork. Case briefs, scoring, /status, /coi, and /override all verified working. Two bugs found and fixed (attestation race condition, rate limiter window). Full voting requires multiple GitHub users. 82/82 local tests passing, 49/49 workflow structural checks passing. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Ran 4 simulated submissions through the full governance pipeline on the fork. Case briefs, scoring, /status, /coi, and /override all verified working. Two bugs found and fixed (attestation race condition, rate limiter window). Full voting requires multiple GitHub users. 82/82 local tests passing, 49/49 workflow structural checks passing. Co-Authored-By: Claude Opus 4.6 <[email protected]>
The /coi workflow adds recused_from edges pointing to issue IDs (e.g., issue-1) that are not seed graph nodes. Updated the integrity test to skip dynamic edges when checking referential integrity. Co-Authored-By: Claude Opus 4.6 <[email protected]>
Allows single-user simulation of the full voting lifecycle by bypassing the submitter-exclusion check when the repository variable GOVERNANCE_TEST_MODE is set to "true". This is a temporary fork-only change for simulation testing. Co-Authored-By: Claude Opus 4.6 <[email protected]>
All panel criticisms addressed: - Split votes (2-1), ties (1-1-1), vote changes tested - Quorum enforcement and collapse via recusal verified - SEC-012 real multi-user enforcement confirmed - Retraction success and failure lifecycle complete - Approve-with-conditions outcome working - Score prediction returns ranges from enriched data - CoI detection flags real graph paths Co-Authored-By: Claude Opus 4.6 <[email protected]>
Introduce lib/workflow-guards.js with reusable functions for: - P0-1: State machine phase guards (checkPhaseGuard) - P0-2: Submitter exclusion from voting (excludeSubmitter, isSubmitterExcluded) - P0-3: Idempotency checks (checkRegistryDuplicate, checkAlreadyRetracted) 46 unit tests covering all guard functions, edge cases, and the PHASE_REQUIREMENTS mapping for every workflow action. Co-Authored-By: Claude Opus 4.6 <[email protected]>
P0-1 (State Machine Guards): - scoring.yml: requires status:triaged, status:scoring, or status:pending-review - escalation-vote.yml: requires status:scoring or status:escalation-vote - validation-vote.yml: requires status:validation-vote - approve-project.yml: requires status:approved or status:approved-with-conditions, plus a bot validation vote result comment (prevents manual label bypass) - retraction.yml (propose): requires status:approved, status:approved-with-conditions, or status:monitoring - retraction.yml (vote): requires status:retraction-proposed All phase guards post an informative comment explaining why the action was blocked and what phase the issue needs to be in. P0-2 (Submitter Exclusion in Retraction): - retraction.yml: excludes the issue author (project submitter) from retraction vote tallies. If the submitter tries to vote, a comment explains they are excluded. Tally messages note the exclusion. - Note: escalation-vote.yml and validation-vote.yml already had SEC-012 submitter exclusion. The retraction workflow was the gap. P0-3 (Idempotency): - approve-project.yml: checks registry for existing entry by issue_number before adding. Skips silently on re-run. - retraction.yml: checks if entry is already retracted before modifying. Skips registry update on re-run. - Both workflows use the concurrency group "registry-update" for serialized access. Also fixed: retraction proposal now applies status:retraction-proposed label, and failed retraction votes restore status:monitoring label. Co-Authored-By: Claude Opus 4.6 <[email protected]>
cancel-in-progress: true was dropping concurrent vote runs. The concurrency group already serializes execution, so switching to false queues runs instead of cancelling in-flight ones. Closes #23 Co-Authored-By: Claude Opus 4.6 <[email protected]>
The job-level if condition only matched status:approved, so projects approved with conditions were never added to the registry. Closes #24 Co-Authored-By: Claude Opus 4.6 <[email protected]>
Runs npm ci and npm test on push to main and pull requests. Uses Node.js 20 with minimal read-only permissions. Actions pinned to SHA consistent with existing workflows. Closes #25 Co-Authored-By: Claude Opus 4.6 <[email protected]>
Create data/committee-config.json with the committee roster and quorum rule. Update validation-vote, escalation-vote, and retraction workflows to compute quorum as simple_majority from config.members instead of hardcoding QUORUM=3. The env var is kept as a fallback if the config file is missing. Scoring workflow does not use quorum, so it is unchanged. Closes #26 Co-Authored-By: Claude Opus 4.6 <[email protected]>
Workflows reference status:approved-with-conditions (validation-vote), status:monitoring and status:retraction-proposed (retraction), and status:triaged (scoring phase guard), but setup-labels.sh did not create them. First run on a fresh repo would leave these workflows unable to apply their labels at runtime. Caught by Copilot review on PR #4 (one comment on approved-with-conditions); the same root cause affects three other labels. Fixing all four together. Also normalizes pre-existing em dash in deferred description.
The score parser used /(\d)/ which captured a single digit, so an input like "mission:10" silently parsed as 1 and was accepted. Switching to \d+ lets the existing 0-5 validation reject values like 10 with the "Could not parse your score" error. Caught by Copilot review on PR #4 (scoring.yml:46 of the reviewed SHA). The lib/commands.parseScore helper already handles this correctly. The inline workflow regex stayed in place to avoid a refactor; once we route scoring.yml through lib/commands.parseScore we can drop the inline regex.
The SEC-010 comment in the script said "strict majority required, ties default to DEFERRED" but the code only checked which bucket had the highest count, not whether that bucket exceeded 50% of votes cast. Concrete failure: 2 approve + 1 decline + 1 defer (4 total) yielded APPROVED on a 50% plurality. Switch to a Math.floor(totalVotes/2)+1 threshold. If combined approve plus approve-with-conditions reaches threshold, prefer with-conditions when its count is >= unconditional approves (preserves prior tie-break direction). If decline reaches threshold, decline. Otherwise defer. Caught by Copilot review on PR #4 (validation-vote.yml:123 of the reviewed SHA).
The script's usage banner advertises "--flags <flags>" but the emitted /score comment used "flags:X". lib/commands.parseScore expects "--flags X", so flags coming through this simulation helper were silently dropped by the workflow regex. Caught by Copilot review on PR #4.
The README voting table and the scoring template's voting commands list both omitted /vote approve-with-conditions and /vote no-retract, even though both are accepted by validation-vote.yml and retraction.yml. Also adds the four status labels that were missing from the README label table to match what setup-labels.sh now creates: status:triaged, status:approved-with-conditions, status:monitoring, status:retraction-proposed. Caught by Copilot review on PR #4 (README.md:56, README.md:68, docs/scoring-template.md:88).
There was a problem hiding this comment.
Pull request overview
Adds a GitHub-native intake and governance pipeline for open-source project submissions, including automated scoring, voting, approval registration, retraction handling, and audit/attestation artifacts.
Changes:
- Introduces GitHub Actions workflows for submission triage, scoring, escalation/validation voting, approval registry updates, retraction, and CI.
- Adds a small Node.js governance library (state machine, workflow guards, command parsing, RVF utilities) plus unit tests.
- Adds governance specs, BDD feature files, documentation, and seed data (committee config, RVF graph/attestation log, approved-projects registry).
Reviewed changes
Copilot reviewed 43 out of 43 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
.github/ISSUE_TEMPLATE/config.yml |
Disables blank issues and adds a contact link. |
.github/ISSUE_TEMPLATE/project-submission.yml |
Adds structured issue form for project submissions with required fields. |
.github/dependabot.yml |
Enables Dependabot updates for GitHub Actions. |
.github/workflows/approve-project.yml |
Registers approved submissions into data/approved-projects.json. |
.github/workflows/ci.yml |
Runs Node tests on PRs and main. |
.github/workflows/escalation-vote.yml |
Tallies escalation votes and advances phase/outcome. |
.github/workflows/on-submission.yml |
Auto-triages new submission issues and applies category label + welcome comment. |
.github/workflows/retraction.yml |
Implements /retract and retraction vote flow + registry update. |
.github/workflows/scoring.yml |
Parses /score comments and posts a score summary. |
.github/workflows/validation-vote.yml |
Tallies validation votes and applies final decision labels (and closes on decline). |
README.md |
Documents submission flow, commands, labels, and admin setup. |
data/approved-projects.json |
Adds the approved-projects registry (initialized empty). |
data/committee-config.json |
Defines committee membership and quorum rule (data-driven). |
data/rvf/attestation.jsonl |
Adds an append-only attestation log with example entries + schema header. |
data/rvf/graph.json |
Seeds an RVF knowledge graph for CoI and example submissions. |
docs/scoring-template.md |
Provides committee-facing scoring template and command reference. |
features/eligibility.feature |
BDD spec for eligibility/intake gates. |
features/gdoc-examples.feature |
BDD spec for end-to-end examples from the governance doc. |
features/retraction.feature |
BDD spec for retraction lifecycle and edge cases. |
features/scoring.feature |
BDD spec for scoring rubric rules and interpretation. |
features/voting.feature |
BDD spec for escalation + validation voting behavior and constraints. |
lib/commands.js |
Implements parsers for /score, /vote, /coi, /override. |
lib/rvf.js |
Implements RVF graph/embedding helpers plus attestation read/append helpers. |
lib/state-machine.js |
Implements a hardcoded governance state machine engine with guard evaluation. |
lib/workflow-guards.js |
Adds reusable guard helpers for phase checks, submitter exclusion, and idempotency checks. |
package.json |
Adds Node test scripts using node --test. |
scripts/setup-labels.sh |
Creates required status/category labels in a target repo. |
scripts/simulate-cleanup.sh |
Closes test issues created by simulation scripts. |
scripts/simulate-full-lifecycle.sh |
Runs a multi-scenario fork-based simulation of the workflows. |
scripts/simulate-scoring.sh |
Posts /score comments for simulations. |
scripts/simulate-submission.sh |
Creates submission issues matching the issue-form output format. |
scripts/simulate-voting.sh |
Posts /vote comments for simulations. |
scripts/verify-workflows.sh |
Adds a local workflow-yaml structure/sanity validator script. |
spec/retraction.yaml |
Adds a retraction-focused governance spec document. |
test/commands.test.js |
Unit tests for slash command parsing. |
test/rvf.test.js |
Unit tests for RVF graph/embeddings and attestation helpers. |
test/state-machine.test.js |
Unit tests for the governance state machine transitions/guards. |
test/workflow-guards.test.js |
Unit tests for phase guards, submitter exclusion, and idempotency helpers. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+51
to
+58
| if [[ "$DELETE" == true ]]; then | ||
| echo " Deleting issue #${number}..." | ||
| gh api \ | ||
| --method DELETE \ | ||
| "/repos/${REPO}/issues/${number}" 2>/dev/null || { | ||
| echo " NOTE: Issue deletion requires admin access. Issue closed but not deleted." | ||
| } | ||
| DELETED=$((DELETED + 1)) |
Comment on lines
+1
to
+6
| {"type":"schema","version":"1.1.0","fields":{"type":"string: transition|decision|attestation","submission_id":"string","from_state":"string","to_state":"string","actor":"string: github_username or 'agent'","timestamp":"string: ISO 8601","gdoc_revision":"string","payload":"object: state-specific data"},"note":"This entry documents the schema. Real entries follow this format. Each line is a single JSON object. This file is append-only. Never edit or delete existing entries. Signature field removed in v1.1.0 -- will be re-added when Ed25519 signing is implemented."} | ||
|
|
||
| {"type":"transition","submission_id":"issue-1","from_state":"new","to_state":"case-brief-generated","actor":"agent","timestamp":"2026-04-18T04:07:47.770Z","gdoc_revision":"","signature":"","payload":{"coi_flags":0,"similar_count":3,"category":"donation"}} | ||
| {"type":"transition","submission_id":"issue-2","from_state":"new","to_state":"case-brief-generated","actor":"agent","timestamp":"2026-04-18T04:07:54.270Z","gdoc_revision":"","signature":"","payload":{"coi_flags":0,"similar_count":3,"category":"website-listing"}} | ||
| {"type":"decision","submission_id":"issue-2","from_state":"active","to_state":"blocked","actor":"michaeloboyle","timestamp":"2026-04-18T04:09:50.551Z","gdoc_revision":"","signature":"","payload":{"action":"self_vote_blocked","command":"/score mission:4 quality:4 clarity:4 impact:4 risk:3"}} | ||
| {"type":"decision","submission_id":"issue-1","from_state":"active","to_state":"coi-recusal","actor":"michaeloboyle","timestamp":"2026-04-18T04:10:00.109Z","gdoc_revision":"","signature":"","payload":{"action":"coi_recusal","reason":"I am affiliated with Acme AI Labs, the submitting organization"}} |
Comment on lines
+260
to
+263
| it('is case-sensitive (GitHub logins are case-sensitive)', () => { | ||
| const result = isSubmitterExcluded('Alice', 'alice'); | ||
| assert.equal(result.excluded, false); | ||
| }); |
| node-version: '20' | ||
|
|
||
| - name: Install dependencies | ||
| run: npm ci |
| issue_number: context.issue.number | ||
| })).data.map(l => l.name); | ||
|
|
||
| const allowedPhases = ['status:triaged', 'status:scoring', 'status:pending-review']; |
Comment on lines
+121
to
+124
| const name = extract('Full Name'); | ||
| const repoUrl = extract('Repository URL'); | ||
| const description = body.match(/### Project Description & Request\s*\n\s*([\s\S]*?)(?=\n###|\n---|\Z)/i); | ||
| const descText = description ? description[1].trim().split('\n')[0] : ''; |
Comment on lines
+376
to
+378
| # Vote retract (SEC-012 does not apply to retraction -- retraction.yml | ||
| # does not exclude the submitter from retraction votes) | ||
| post_vote "$ISSUE4" "retract" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a GitHub-native intake and governance pipeline for open source project submissions to the Agentics Foundation. Members open an issue using the project-submission template; GitHub Actions workflows handle scoring, escalation voting, validation voting, registration of approved projects, and retraction. Decisions are recorded as immutable comments plus an append-only attestation log. Committee composition and quorum come from
data/committee-config.json, not from code.This work was originally proposed in #4. After review three classes of issue surfaced: governance gaps that allowed phase bypass, spec drift surfaced by Copilot bot on 2026-04-30, and branch-hygiene constraints (#4 was opened with
michaeloboyle:mainas head, which couples every update to the fork's main branch and conflicts with our safety policy of blocking direct pushes to main). This PR addresses all three on a feature branch and supersedes #4.What's in the pipeline
.github/ISSUE_TEMPLATE/project-submission.yml.github/workflows/scoring.yml.github/workflows/escalation-vote.yml,validation-vote.yml.github/workflows/approve-project.yml/retractflow.github/workflows/retraction.ymllib/workflow-guards.jsdata/committee-config.jsondata/rvf/attestation.jsonldocs/scoring-template.mdP0 governance fixes
These three close bypass and replay holes. They are not refactors.
scoring,escalation-vote,validation-vote,approve-project, andretractioneach verify the issue is in the correct phase before acting. Without this, anyone with write access could manually applystatus:approvedand skip voting entirely.approve-projectchecks for existing registry entries;retractionchecks for existing label transitions. Re-running a workflow no longer creates duplicates inapproved-projects.json.Supporting changes that emerged during P0 work:
workflow-guardslibrary with 129 passing tests across 13 suitesnpm teston every PRapprove-project.yml(was a documented state with no transition path)data/committee-config.jsoninstead of hardcoded3Copilot review dispositions
Copilot bot posted 13 file-line comments on #4 head
263000aon 2026-04-30. 5 are directly fixed on this branch. 8 are already resolved by intermediate work, outdated against rewritten files, or filed as follow-ups.scripts/simulate-scoring.sh:90--flagssyntax mismatch with documented format8ca5e0elib/state-machine.js:45rescoringandretraction_escalatedstates not modeled.github/workflows/retraction.yml:168coreundefined in shell stepcoreauto-injected via github-script.github/workflows/retraction.yml:107b539e7e+a79600d.github/workflows/validation-vote.yml:1230d88f27.github/workflows/scoring.yml:4675f1455scripts/setup-labels.sh:297e7c4d6README.md:56b00caacdata/rvf/attestation.jsonl:5.github/workflows/retraction.yml:17/retractexact-match vs/retract <reason>BDD spec mismatch.github/workflows/approve-project.yml:14c90188bREADME.md:68b00caac)b00caacdocs/scoring-template.md:88Tests
npm testreports 129/129 passing across 13 suites on this branch HEAD (b00caac). CI is wired to run on every PR via.github/workflows/ci.yml.Test Plan (committee verification)
setup-labels.shcreates all required labels in the upstream repomission:10is rejected as out-of-range, not silently truncated/vote retract no-retract, the vote is excluded and the tally proceeds without their inputFollow-ups (filed separately)
data/rvf/attestation.jsonl:5schema drift — signatures referenced in records do not match the schema fields actually written.github/workflows/retraction.yml:17/retractexact-match — current trigger does not accept the documented/retract <reason>form per the BDD speclib/state-machine.js:45rescoringandretraction_escalated— tracked at fork issue #31