ci: soften contribution intake gates
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
name: Contribution gate - issues
|
name: Contribution intake - issues
|
||||||
|
|
||||||
on:
|
on:
|
||||||
issues:
|
issues:
|
||||||
@@ -8,16 +8,11 @@ permissions:
|
|||||||
contents: read
|
contents: read
|
||||||
issues: write
|
issues: write
|
||||||
|
|
||||||
env:
|
|
||||||
# Keep new gates observable first. Switch to "enforce" only after maintainers
|
|
||||||
# have seeded active contributors and reviewed the dry-run signal.
|
|
||||||
CONTRIBUTION_GATE_MODE: dry-run
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
gate:
|
gate:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Gate unapproved external issues
|
- name: Welcome new external issue reporters
|
||||||
uses: actions/github-script@v7
|
uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
@@ -25,12 +20,6 @@ jobs:
|
|||||||
const owner = context.repo.owner;
|
const owner = context.repo.owner;
|
||||||
const repo = context.repo.repo;
|
const repo = context.repo.repo;
|
||||||
const privileged = new Set(['OWNER', 'MEMBER', 'COLLABORATOR']);
|
const privileged = new Set(['OWNER', 'MEMBER', 'COLLABORATOR']);
|
||||||
const gateMode = (process.env.CONTRIBUTION_GATE_MODE || 'dry-run').trim().toLowerCase();
|
|
||||||
const enforceGate = gateMode === 'enforce';
|
|
||||||
|
|
||||||
if (!['dry-run', 'enforce'].includes(gateMode)) {
|
|
||||||
core.warning(`Unknown CONTRIBUTION_GATE_MODE "${gateMode}"; defaulting to dry-run.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (privileged.has(issue.author_association)) return;
|
if (privileged.has(issue.author_association)) return;
|
||||||
if (issue.user.login === 'github-actions[bot]') return;
|
if (issue.user.login === 'github-actions[bot]') return;
|
||||||
@@ -71,29 +60,25 @@ jobs:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gateMessage = enforceGate
|
const marker = '<!-- codewhale-issue-intake -->';
|
||||||
? 'This repository currently uses a maintainer-managed contribution gate, so issues from contributors who are not listed in `.github/APPROVED_CONTRIBUTORS` are closed automatically.'
|
const { data: comments } = await github.rest.issues.listComments({
|
||||||
: 'This repository is currently observing a maintainer-managed contribution gate in dry-run mode, so this issue is staying open. When enforcement is enabled, issues from contributors who are not listed in `.github/APPROVED_CONTRIBUTORS` will be closed automatically.';
|
owner,
|
||||||
|
repo,
|
||||||
|
issue_number: issue.number,
|
||||||
|
per_page: 100,
|
||||||
|
});
|
||||||
|
if (comments.some(comment => (comment.body || '').includes(marker))) return;
|
||||||
|
|
||||||
await github.rest.issues.createComment({
|
await github.rest.issues.createComment({
|
||||||
owner,
|
owner,
|
||||||
repo,
|
repo,
|
||||||
issue_number: issue.number,
|
issue_number: issue.number,
|
||||||
body: [
|
body: [
|
||||||
|
marker,
|
||||||
`Thanks @${issue.user.login} for the report.`,
|
`Thanks @${issue.user.login} for the report.`,
|
||||||
'',
|
'',
|
||||||
gateMessage,
|
'This issue is staying open for maintainer triage. CodeWhale gets better because people bring us real edge cases from real machines, providers, regions, and workflows.',
|
||||||
'',
|
'',
|
||||||
'Please read `CONTRIBUTING.md` for the expected issue shape. A maintainer can grant issue access by commenting `/lgtmi` on an issue.',
|
'If you can add a reproduction, logs, version output, screenshots, or the provider/model involved, that makes it much easier for us to verify and harvest the fix. Maintainers may comment `/lgtmi` to mark recurring issue reporters as approved so this intake note is skipped next time.',
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!enforceGate) return;
|
|
||||||
|
|
||||||
await github.rest.issues.update({
|
|
||||||
owner,
|
|
||||||
repo,
|
|
||||||
issue_number: issue.number,
|
|
||||||
state: 'closed',
|
|
||||||
state_reason: 'not_planned',
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -73,8 +73,8 @@ jobs:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const gateMessage = enforceGate
|
const gateMessage = enforceGate
|
||||||
? 'This repository currently uses a maintainer-managed contribution gate, so pull requests from contributors who are not listed in `.github/APPROVED_CONTRIBUTORS` are closed automatically.'
|
? 'This repository currently limits automated PR intake to contributors listed in `.github/APPROVED_CONTRIBUTORS`. This is a maintainer-safety control for code review and CI load, not a judgment on the contribution. A maintainer can reopen or grant access with `/lgtm` after review.'
|
||||||
: 'This repository is currently observing a maintainer-managed contribution gate in dry-run mode, so this pull request is staying open. When enforcement is enabled, pull requests from contributors who are not listed in `.github/APPROVED_CONTRIBUTORS` will be closed automatically.';
|
: 'This repository is observing a maintainer-managed PR intake gate in dry-run mode, so this pull request is staying open. This note helps maintainers prepare the allowlist before any enforcement is considered.';
|
||||||
|
|
||||||
await github.rest.issues.createComment({
|
await github.rest.issues.createComment({
|
||||||
owner,
|
owner,
|
||||||
@@ -85,7 +85,7 @@ jobs:
|
|||||||
'',
|
'',
|
||||||
gateMessage,
|
gateMessage,
|
||||||
'',
|
'',
|
||||||
'Please read `CONTRIBUTING.md` for the expected contribution shape. A maintainer can grant PR access by commenting `/lgtm` on a pull request.',
|
'Please read `CONTRIBUTING.md` for the expected contribution shape. A maintainer can grant recurring PR access by commenting `/lgtm` on a pull request.',
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Appended volatile `<turn_meta>` blocks after user text in outgoing user
|
- Appended volatile `<turn_meta>` blocks after user text in outgoing user
|
||||||
message content arrays so provider prefix caches can keep matching the stable
|
message content arrays so provider prefix caches can keep matching the stable
|
||||||
user-input prefix across date, route, and working-set changes.
|
user-input prefix across date, route, and working-set changes.
|
||||||
|
- Softened contribution intake automation: external issues now receive a warm
|
||||||
|
triage note and are never auto-closed by the contribution gate, while the PR
|
||||||
|
gate copy makes clear that dry-run observations are about maintainer safety,
|
||||||
|
not contributor quality.
|
||||||
|
- Documented the agent and sub-agent stewardship ethos so future automation
|
||||||
|
preserves human issue intake, careful PR review, and contributor credit.
|
||||||
|
|
||||||
### Community
|
### Community
|
||||||
|
|
||||||
|
|||||||
+26
-14
@@ -172,16 +172,24 @@ Validation:
|
|||||||
CodeWhale uses a maintainer-managed contribution gate for the community front
|
CodeWhale uses a maintainer-managed contribution gate for the community front
|
||||||
door. Maintainers and collaborators bypass this gate automatically. The gate
|
door. Maintainers and collaborators bypass this gate automatically. The gate
|
||||||
workflows default to dry-run / comment-only mode so maintainers can observe the
|
workflows default to dry-run / comment-only mode so maintainers can observe the
|
||||||
signal before closing contributor work. In dry-run mode, unapproved external
|
signal before changing contributor flow.
|
||||||
issues and pull requests receive a short thank-you / CONTRIBUTING pointer and
|
|
||||||
remain open.
|
|
||||||
|
|
||||||
When maintainers are ready to enforce the gate, set
|
The maintainer posture is documented in
|
||||||
`CONTRIBUTION_GATE_MODE: enforce` in the PR and issue gate workflows. In enforce
|
[docs/AGENT_ETHOS.md](docs/AGENT_ETHOS.md): automation should reduce load while
|
||||||
mode, external contributors must be listed in
|
keeping good-faith contributors seen, credited, and able to keep helping.
|
||||||
`.github/APPROVED_CONTRIBUTORS` before their issues or pull requests remain
|
|
||||||
open. Before enabling enforcement, seed the allowlist broadly enough for active
|
Issues are never auto-closed by the contribution gate. Unapproved external
|
||||||
external contributors who should not be interrupted by the rollout.
|
issues receive a short welcome note that asks for reproduction details and then
|
||||||
|
remain open for maintainer triage. CodeWhale depends on real edge cases from
|
||||||
|
real users, so issue intake should stay warm and open.
|
||||||
|
|
||||||
|
Pull requests are different because they can touch code, CI, release plumbing,
|
||||||
|
auth, sandboxing, provider policy, and other trust-boundary surfaces. The PR
|
||||||
|
gate can be switched from dry-run to enforcement when maintainers decide they
|
||||||
|
need that safety control, but it should be treated as a review-load control,
|
||||||
|
not a judgment on contributor quality. Before enabling PR enforcement, seed the
|
||||||
|
allowlist broadly enough for active external contributors who should not be
|
||||||
|
interrupted by the rollout.
|
||||||
|
|
||||||
The allowlist is scoped:
|
The allowlist is scoped:
|
||||||
|
|
||||||
@@ -198,11 +206,10 @@ discussion.
|
|||||||
Approvals do not edit `main` directly. The approval workflow opens a small
|
Approvals do not edit `main` directly. The approval workflow opens a small
|
||||||
allowlist update PR so the new entry is reviewable before it takes effect.
|
allowlist update PR so the new entry is reviewable before it takes effect.
|
||||||
|
|
||||||
If the gate fires on a good contributor incorrectly, use the same approval flow
|
If the PR gate fires on a good contributor incorrectly, use the same approval
|
||||||
to restore them: comment `/lgtm` or `/lgtmi`, merge the generated allowlist PR,
|
flow to restore them: comment `/lgtm`, merge the generated allowlist PR, then
|
||||||
then reopen the affected issue or pull request. If GitHub will not allow the
|
reopen the affected pull request. If GitHub will not allow the closed PR to be
|
||||||
closed item to be reopened, ask the contributor to resubmit after the allowlist
|
reopened, ask the contributor to resubmit after the allowlist PR is merged.
|
||||||
PR is merged.
|
|
||||||
|
|
||||||
## Agent-Assisted Improvements
|
## Agent-Assisted Improvements
|
||||||
|
|
||||||
@@ -213,6 +220,11 @@ from a fresh fork or branch, let the agent find exactly one small friction point
|
|||||||
and stop after one patch. DeepSeek V4 Pro is the first-class path for this loop
|
and stop after one patch. DeepSeek V4 Pro is the first-class path for this loop
|
||||||
today, but the review shape matters more than the provider.
|
today, but the review shape matters more than the provider.
|
||||||
|
|
||||||
|
Agents and maintainers should follow the stewardship posture in
|
||||||
|
[docs/AGENT_ETHOS.md](docs/AGENT_ETHOS.md): use automation for evidence,
|
||||||
|
verification, and narrow patches while keeping the final community decision
|
||||||
|
human-reviewed.
|
||||||
|
|
||||||
The useful output is not "ideas for improvement." The useful output is a
|
The useful output is not "ideas for improvement." The useful output is a
|
||||||
specific reproduction, a minimal diff, focused checks, and a PR description that
|
specific reproduction, a minimal diff, focused checks, and a PR description that
|
||||||
explains the trade-off. Do not use an agent to touch auth, credentials, sandbox
|
explains the trade-off. Do not use an agent to touch auth, credentials, sandbox
|
||||||
|
|||||||
@@ -545,6 +545,7 @@ without recreating skills the user deliberately deleted.
|
|||||||
| [TENCENT_CLOUD_REMOTE_FIRST.md](docs/TENCENT_CLOUD_REMOTE_FIRST.md) | Tencent/CNB/Lighthouse/Feishu remote-first path |
|
| [TENCENT_CLOUD_REMOTE_FIRST.md](docs/TENCENT_CLOUD_REMOTE_FIRST.md) | Tencent/CNB/Lighthouse/Feishu remote-first path |
|
||||||
| [TENCENT_LIGHTHOUSE_HK.md](docs/TENCENT_LIGHTHOUSE_HK.md) | Lighthouse Hong Kong server setup |
|
| [TENCENT_LIGHTHOUSE_HK.md](docs/TENCENT_LIGHTHOUSE_HK.md) | Lighthouse Hong Kong server setup |
|
||||||
| [MEMORY.md](docs/MEMORY.md) | User memory feature guide |
|
| [MEMORY.md](docs/MEMORY.md) | User memory feature guide |
|
||||||
|
| [AGENT_ETHOS.md](docs/AGENT_ETHOS.md) | Maintainer and agent stewardship posture |
|
||||||
| [SUBAGENTS.md](docs/SUBAGENTS.md) | Sub-agent role taxonomy and lifecycle |
|
| [SUBAGENTS.md](docs/SUBAGENTS.md) | Sub-agent role taxonomy and lifecycle |
|
||||||
| [KEYBINDINGS.md](docs/KEYBINDINGS.md) | Full shortcut catalog |
|
| [KEYBINDINGS.md](docs/KEYBINDINGS.md) | Full shortcut catalog |
|
||||||
| [RELEASE_RUNBOOK.md](docs/RELEASE_RUNBOOK.md) | Release process |
|
| [RELEASE_RUNBOOK.md](docs/RELEASE_RUNBOOK.md) | Release process |
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# Agent Ethos
|
||||||
|
|
||||||
|
CodeWhale is maintained with agents, but it is not maintained by automation
|
||||||
|
alone. Treat community reports and patches as real collaboration: people are
|
||||||
|
bringing us machines, providers, regions, shells, packages, and edge cases we
|
||||||
|
could not cover by ourselves.
|
||||||
|
|
||||||
|
## Stewardship
|
||||||
|
|
||||||
|
- Verify live truth before acting. Check the current branch, release state,
|
||||||
|
registry state, CI, and linked issues instead of trusting a handoff.
|
||||||
|
- Issues are intake, not a privilege boundary. Do not auto-close good-faith
|
||||||
|
issues because the reporter is not allowlisted. Ask for missing reproduction
|
||||||
|
detail and leave room for maintainer triage.
|
||||||
|
- PR gates exist for code review, CI load, and trust-boundary safety. They are
|
||||||
|
not a quality judgment on the contributor. Keep dry-run mode unless a
|
||||||
|
maintainer deliberately enables enforcement, and use warm copy when the gate
|
||||||
|
comments.
|
||||||
|
- Be generous with recurring contributors. When someone repeatedly brings
|
||||||
|
useful reports or patches, use `/lgtmi` for issue access or `/lgtm` for PR
|
||||||
|
access so the automation gets out of their way.
|
||||||
|
- Preserve contributor credit. When harvesting work, inspect the PR and linked
|
||||||
|
issues, keep author/co-author attribution where possible, add
|
||||||
|
`Harvested from PR #N by @handle`, and credit the contributor in the
|
||||||
|
changelog or release notes.
|
||||||
|
- Deferral is a maintainer action, not a dismissal. If a PR or issue is not
|
||||||
|
ready, say what is blocked, what evidence would change the decision, and
|
||||||
|
which part of the work remains valuable.
|
||||||
|
|
||||||
|
## Agent Workflow
|
||||||
|
|
||||||
|
- Use sub-agents for exploration, review, and verification, but keep a human
|
||||||
|
maintainer posture in the parent session. Sub-agent output is evidence; the
|
||||||
|
parent is responsible for the final decision.
|
||||||
|
- Personally review community PRs before merging, harvesting, closing, or
|
||||||
|
deferring them. Do not close work based only on title, labels, or an agent's
|
||||||
|
summary.
|
||||||
|
- Prefer narrow, reversible changes that match the existing codebase. Avoid
|
||||||
|
drive-by refactors while harvesting community work.
|
||||||
|
- Run the smallest meaningful validation first, then broaden tests when a
|
||||||
|
change touches shared behavior, release plumbing, auth, sandboxing,
|
||||||
|
providers, or UI workflows.
|
||||||
|
- Do not tag, publish, push release artifacts, or create GitHub releases
|
||||||
|
without explicit maintainer approval.
|
||||||
|
|
||||||
|
## Product Tone
|
||||||
|
|
||||||
|
CodeWhale should feel like a capable coding harness with a public community,
|
||||||
|
not a closed queue. Automation should reduce maintainer load while making
|
||||||
|
contributors feel seen, credited, and able to keep helping.
|
||||||
@@ -18,6 +18,19 @@ The `type` field on `agent_open` selects a system-prompt posture for the child
|
|||||||
(`agent_type` is accepted as a compatibility alias). Each role is a distinct
|
(`agent_type` is accepted as a compatibility alias). Each role is a distinct
|
||||||
stance toward the work — not just a different label.
|
stance toward the work — not just a different label.
|
||||||
|
|
||||||
|
## Maintainer posture
|
||||||
|
|
||||||
|
Sub-agents help CodeWhale move faster, but the parent agent still owns the
|
||||||
|
maintainer decision. Use children to gather evidence, review patches, and run
|
||||||
|
verification while keeping the community posture in
|
||||||
|
[`AGENT_ETHOS.md`](AGENT_ETHOS.md): issues are open intake, PR gates are
|
||||||
|
review-load controls, and harvested work needs clear contributor credit.
|
||||||
|
|
||||||
|
When a child reviews community work, the parent should still inspect the PR
|
||||||
|
diff, linked issues, tests, and CI before merging, harvesting, closing, or
|
||||||
|
deferring it. A sub-agent's result is a working set, not a substitute for
|
||||||
|
stewardship.
|
||||||
|
|
||||||
| Role | Stance | Writes? | Shell posture | Typical use |
|
| Role | Stance | Writes? | Shell posture | Typical use |
|
||||||
|---------------|----------------------------------------|---------|---------------|----------------------------------------------|
|
|---------------|----------------------------------------|---------|---------------|----------------------------------------------|
|
||||||
| `general` | flexible; do whatever the parent says | yes | yes | the default; multi-step tasks |
|
| `general` | flexible; do whatever the parent says | yes | yes | the default; multi-step tasks |
|
||||||
|
|||||||
Reference in New Issue
Block a user