mirror of https://github.com/garrytan/gstack.git
chore: revert pty-smoke harness experiments (race-retry + CI debug step)
Diagnosis is conclusive and the experiments aren't the fix, so restore the harness to its original state (net-zero diff vs main for both files). What the CI debug step proved: `claude -p` returns READY — claude v2.1.187 fully DISCOVERS /office-hours from the symlinked registry. Only the interactive PTY TUI rejects it as "Unknown command" (and it received the full command text). So the e2e-pty-plan-smoke failure is a claude 2.1.187 interactive-TUI regression (skills discovered by `claude -p` aren't exposed as TUI slash commands), pre-existing in the #2077 harness and failing identically on its own origin branch — unrelated to this activation PR. The race-retry can't help (the TUI genuinely lacks the command); the debug step also tripped actionlint (shellcheck SC2012). Both reverted.
This commit is contained in:
parent
9e85de551e
commit
525254455a
|
|
@ -216,24 +216,6 @@ jobs:
|
||||||
|| { echo "ERROR: plan-ceo-review SKILL.md missing 'name: plan-ceo-review' frontmatter" >&2; exit 1; }
|
|| { echo "ERROR: plan-ceo-review SKILL.md missing 'name: plan-ceo-review' frontmatter" >&2; exit 1; }
|
||||||
echo "skill registry OK"
|
echo "skill registry OK"
|
||||||
|
|
||||||
# TEMP DEBUG (remove after diagnosing pty-smoke discovery): the smoke fails
|
|
||||||
# with "Unknown command: /office-hours" even after retries (not a race).
|
|
||||||
# Capture what claude actually discovers in CI to fix the registry precisely.
|
|
||||||
- name: Debug skill discovery (pty smoke)
|
|
||||||
if: matrix.suite.name == 'e2e-pty-plan-smoke'
|
|
||||||
env:
|
|
||||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
||||||
run: |
|
|
||||||
set +e
|
|
||||||
echo "=== claude version + binary ==="; command -v claude; claude --version 2>&1 | head -3
|
|
||||||
echo "=== HOME/CLAUDE/XDG env ==="; env | grep -iE '^(HOME|CLAUDE|XDG)=' || true
|
|
||||||
echo "=== ~/.claude/skills (top) ==="; ls -la "$HOME/.claude/skills" 2>&1 | head -30
|
|
||||||
echo "=== office-hours SKILL.md resolves? ==="; head -3 "$HOME/.claude/skills/office-hours/SKILL.md" 2>&1
|
|
||||||
echo "=== project .claude in cwd? ==="; ls -la "$GITHUB_WORKSPACE/.claude" 2>&1 | head
|
|
||||||
echo "=== claude -p probe (same discovery path) ==="
|
|
||||||
cd "$GITHUB_WORKSPACE"
|
|
||||||
timeout 90 claude -p "Reply with exactly the word READY and nothing else if the /office-hours slash command is available to you, otherwise reply MISSING." 2>&1 | tail -10
|
|
||||||
|
|
||||||
- name: Run ${{ matrix.suite.name }}
|
- name: Run ${{ matrix.suite.name }}
|
||||||
env:
|
env:
|
||||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||||
|
|
|
||||||
|
|
@ -1605,7 +1605,7 @@ export async function runPlanSkillObservation(opts: {
|
||||||
// command.
|
// command.
|
||||||
await Bun.sleep(3000);
|
await Bun.sleep(3000);
|
||||||
}
|
}
|
||||||
let since = session.mark();
|
const since = session.mark();
|
||||||
session.send(`/${opts.skillName}\r`);
|
session.send(`/${opts.skillName}\r`);
|
||||||
|
|
||||||
const budgetMs = opts.timeoutMs ?? 180_000;
|
const budgetMs = opts.timeoutMs ?? 180_000;
|
||||||
|
|
@ -1619,7 +1619,6 @@ export async function runPlanSkillObservation(opts: {
|
||||||
// even if the current state is 'working'.
|
// even if the current state is 'working'.
|
||||||
let proseAUQEverObserved = false;
|
let proseAUQEverObserved = false;
|
||||||
let waitingEverObserved = false;
|
let waitingEverObserved = false;
|
||||||
let unknownCmdRetries = 0;
|
|
||||||
const JUDGE_AFTER_MS = 60_000;
|
const JUDGE_AFTER_MS = 60_000;
|
||||||
const JUDGE_INTERVAL_MS = 30_000;
|
const JUDGE_INTERVAL_MS = 30_000;
|
||||||
while (Date.now() - start < budgetMs) {
|
while (Date.now() - start < budgetMs) {
|
||||||
|
|
@ -1635,24 +1634,9 @@ export async function runPlanSkillObservation(opts: {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (visible.includes('Unknown command:')) {
|
if (visible.includes('Unknown command:')) {
|
||||||
// Skill-discovery race: in a cold CI container the overlay-FS scan of
|
|
||||||
// the symlinked ~/.claude/skills registry can finish AFTER the boot
|
|
||||||
// grace, so the first `/skill` send reaches claude before the skill is
|
|
||||||
// indexed and is rejected as unknown. (Reproduces only in CI — passes
|
|
||||||
// locally where claude is warm and discovery is instant.) Re-send the
|
|
||||||
// command a few times, re-marking first so the stale "Unknown command:"
|
|
||||||
// line in scrollback can't immediately re-trip this check, before
|
|
||||||
// concluding the skill is genuinely unregistered.
|
|
||||||
if (unknownCmdRetries < 3) {
|
|
||||||
unknownCmdRetries++;
|
|
||||||
await Bun.sleep(6000);
|
|
||||||
since = session.mark();
|
|
||||||
session.send(`/${opts.skillName}\r`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
outcome: 'exited',
|
outcome: 'exited',
|
||||||
summary: `claude rejected /${opts.skillName} as unknown command after ${unknownCmdRetries} retries (skill not registered in this cwd)`,
|
summary: `claude rejected /${opts.skillName} as unknown command (skill not registered in this cwd)`,
|
||||||
evidence: visible.slice(-2000),
|
evidence: visible.slice(-2000),
|
||||||
elapsedMs: Date.now() - startedAt,
|
elapsedMs: Date.now() - startedAt,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue