refactor: remove dead contributor mode, replace with operational self-improvement slot

Contributor mode never fired in 18 days of heavy use (required manual opt-in
via gstack-config, gated behind _CONTRIB=true, wrote disconnected markdown).

Removes: generateContributorMode(), _CONTRIB bash var, 2 E2E tests, touchfile
entry, doc references. Cleans up skip-lists in plan-ceo-review, autoplan,
review resolver, and document-release templates.

The operational self-improvement system (next commit) replaces this slot with
automatic learning capture that requires no opt-in.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-03-29 21:02:50 -07:00
parent ae0a9ad195
commit b6fcfd84b7
37 changed files with 18 additions and 650 deletions
+4 -4
View File
@@ -213,11 +213,11 @@ describe('gen-skill-docs', () => {
expect(browseTmpl).toContain('{{PREAMBLE}}');
});
test('generated SKILL.md contains contributor mode check', () => {
test('generated SKILL.md contains no contributor mode (removed)', () => {
const content = fs.readFileSync(path.join(ROOT, 'SKILL.md'), 'utf-8');
expect(content).toContain('Contributor Mode');
expect(content).toContain('gstack_contributor');
expect(content).toContain('contributor-logs');
expect(content).not.toContain('Contributor Mode');
expect(content).not.toContain('gstack_contributor');
expect(content).not.toContain('contributor-logs');
});
test('generated SKILL.md contains session awareness', () => {
-2
View File
@@ -41,7 +41,6 @@ export const E2E_TOUCHFILES: Record<string, string[]> = {
'skillmd-no-local-binary': ['SKILL.md', 'SKILL.md.tmpl', 'scripts/gen-skill-docs.ts'],
'skillmd-outside-git': ['SKILL.md', 'SKILL.md.tmpl', 'scripts/gen-skill-docs.ts'],
'contributor-mode': ['SKILL.md.tmpl', 'scripts/gen-skill-docs.ts'],
'session-awareness': ['SKILL.md', 'SKILL.md.tmpl', 'scripts/gen-skill-docs.ts'],
// QA (+ test-server dependency)
@@ -182,7 +181,6 @@ export const E2E_TIERS: Record<string, 'gate' | 'periodic'> = {
'skillmd-setup-discovery': 'gate',
'skillmd-no-local-binary': 'gate',
'skillmd-outside-git': 'gate',
'contributor-mode': 'gate',
'session-awareness': 'gate',
// QA — gate for functional, periodic for quality/benchmarks
-45
View File
@@ -177,51 +177,6 @@ Report the exact output — either "READY: <path>" or "NEEDS_SETUP".`,
try { fs.rmSync(nonGitDir, { recursive: true, force: true }); } catch {}
}, 60_000);
testConcurrentIfSelected('contributor-mode', async () => {
const contribDir = fs.mkdtempSync(path.join(os.tmpdir(), 'skill-e2e-contrib-'));
const logsDir = path.join(contribDir, 'contributor-logs');
fs.mkdirSync(logsDir, { recursive: true });
const result = await runSkillTest({
prompt: `You are in contributor mode (gstack_contributor=true). You just ran this browse command and it failed:
$ /nonexistent/browse goto https://example.com
/nonexistent/browse: No such file or directory
Per the contributor mode instructions, file a field report to ${logsDir}/browse-missing-binary.md using the Write tool. Include all required sections: title, what you tried, what happened, rating, repro steps, raw output, what would make it a 10, and the date/version footer.`,
workingDirectory: contribDir,
maxTurns: 5,
timeout: 30_000,
testName: 'contributor-mode',
runId,
});
logCost('contributor mode', result);
// Override passed: this test intentionally triggers a browse error (nonexistent binary)
// so browseErrors will be non-empty — that's expected, not a failure
recordE2E(evalCollector, 'contributor mode report', 'Skill E2E tests', result, {
passed: result.exitReason === 'success',
});
// Verify a contributor log was created with expected format
const logFiles = fs.readdirSync(logsDir).filter(f => f.endsWith('.md'));
expect(logFiles.length).toBeGreaterThan(0);
// Verify report has key structural sections (agent may phrase differently)
const logContent = fs.readFileSync(path.join(logsDir, logFiles[0]), 'utf-8');
// Must have a title (# heading)
expect(logContent).toMatch(/^#\s/m);
// Must mention the failed command or browse
expect(logContent).toMatch(/browse|nonexistent|not found|no such file/i);
// Must have some kind of rating
expect(logContent).toMatch(/rating|\/10/i);
// Must have steps or reproduction info
expect(logContent).toMatch(/step|repro|reproduce/i);
// Clean up
try { fs.rmSync(contribDir, { recursive: true, force: true }); } catch {}
}, 90_000);
testConcurrentIfSelected('session-awareness', async () => {
const sessionDir = fs.mkdtempSync(path.join(os.tmpdir(), 'skill-e2e-session-'));
-56
View File
@@ -325,62 +325,6 @@ Report the exact output — either "READY: <path>" or "NEEDS_SETUP".`,
try { fs.rmSync(nonGitDir, { recursive: true, force: true }); } catch {}
}, 60_000);
testIfSelected('contributor-mode', async () => {
const contribDir = fs.mkdtempSync(path.join(os.tmpdir(), 'skill-e2e-contrib-'));
const logsDir = path.join(contribDir, 'contributor-logs');
fs.mkdirSync(logsDir, { recursive: true });
// Extract contributor mode instructions from generated SKILL.md
const skillMd = fs.readFileSync(path.join(ROOT, 'SKILL.md'), 'utf-8');
const contribStart = skillMd.indexOf('## Contributor Mode');
const contribEnd = skillMd.indexOf('\n## ', contribStart + 1);
const contribBlock = skillMd.slice(contribStart, contribEnd > 0 ? contribEnd : undefined);
const result = await runSkillTest({
prompt: `You are in contributor mode (_CONTRIB=true).
${contribBlock}
OVERRIDE: Write contributor logs to ${logsDir}/ instead of ~/.gstack/contributor-logs/
Now try this browse command (it will fail there is no binary at this path):
/nonexistent/path/browse goto https://example.com
This is a gstack issue (the browse binary is missing/misconfigured).
File a contributor report about this issue. Then tell me what you filed.`,
workingDirectory: contribDir,
maxTurns: 8,
timeout: 60_000,
testName: 'contributor-mode',
runId,
});
logCost('contributor mode', result);
// Override passed: this test intentionally triggers a browse error (nonexistent binary)
// so browseErrors will be non-empty — that's expected, not a failure
recordE2E('contributor mode report', 'Skill E2E tests', result, {
passed: result.exitReason === 'success',
});
// Verify a contributor log was created with expected format
const logFiles = fs.readdirSync(logsDir).filter(f => f.endsWith('.md'));
expect(logFiles.length).toBeGreaterThan(0);
// Verify new reflection-based format
const logContent = fs.readFileSync(path.join(logsDir, logFiles[0]), 'utf-8');
expect(logContent).toContain('Hey gstack team');
expect(logContent).toContain('What I was trying to do');
expect(logContent).toContain('What happened instead');
expect(logContent).toMatch(/rating/i);
// Verify report has repro steps (agent may use "Steps to reproduce", "Repro Steps", etc.)
expect(logContent).toMatch(/repro|steps to reproduce|how to reproduce/i);
// Verify report has date/version footer (agent may format differently)
expect(logContent).toMatch(/date.*2026|2026.*date/i);
// Clean up
try { fs.rmSync(contribDir, { recursive: true, force: true }); } catch {}
}, 90_000);
testIfSelected('session-awareness', async () => {
const sessionDir = fs.mkdtempSync(path.join(os.tmpdir(), 'skill-e2e-session-'));