fix(config): repo_mode keeps its empty no-default semantics (#2611 follow-up)

The ported defaults table synthesized repo_mode → "unknown", but EMPTY is
load-bearing for that key: gstack-repo-mode treats any non-empty answer as a
user override and skips its own repo classification — the synthesized default
turned the classifier into dead code (REPO_MODE=unknown everywhere; caught by
test/gstack-repo-mode.test.ts via the wave's cross-agent blame protocol).
repo_mode joins the empty-is-real carve-outs (empty output, exit 0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-17 10:43:32 -07:00
co-authored by Claude Fable 5
parent 2494276742
commit 565ca9b13b
2 changed files with 11 additions and 4 deletions
+5 -1
View File
@@ -167,7 +167,11 @@ lookup_default() {
question_tuning) echo "false" ;;
team_mode) echo "false" ;;
transcript_ingest_mode) echo "off" ;;
repo_mode) echo "unknown" ;;
# repo_mode: EMPTY is load-bearing — gstack-repo-mode treats any non-empty
# answer as a user override and skips its own classification entirely, so
# a synthesized "unknown" default turns the classifier into dead code.
# Empty + exit 0 = "no override set, go classify".
repo_mode) echo "" ;;
# Unknown key: exit non-zero instead of printing "". The fallback pattern
# the preambles use,
# VAR=$(gstack-config get <key> 2>/dev/null || echo "<default>")
+6 -3
View File
@@ -123,15 +123,18 @@ describe('gstack-config defaults (gate, free)', () => {
});
test('a known key whose default is intentionally empty still exits 0', () => {
for (const key of ['cross_project_learnings', 'salience_allowlist', 'redact_repo_visibility']) {
// repo_mode is in this class BY CONTRACT: gstack-repo-mode treats any
// non-empty answer as a user override and skips classification, so a
// synthesized "unknown" default would turn the classifier into dead code
// (caught live by test/gstack-repo-mode.test.ts during the wave).
for (const key of ['cross_project_learnings', 'salience_allowlist', 'redact_repo_visibility', 'repo_mode']) {
expect({ key, ...get(key) }).toEqual({ key, out: '', code: 0 });
}
});
test('the four keys that regressed resolve to the values their callers assume', () => {
test('the regressed keys resolve to the values their callers assume', () => {
expect(get('question_tuning').out).toBe('false');
expect(get('team_mode').out).toBe('false');
expect(get('transcript_ingest_mode').out).toBe('off');
expect(get('repo_mode').out).toBe('unknown');
});
});