test: repin ~70 assertions to the script contract — every literal gets a successor

Assertions that pinned inline-bash internals (update-check guard, _SESSIONS
reaping, telemetry start/end blocks, routing probe, repo-strip producer,
first-task gating, EXPLAIN_LEVEL/QUESTION_TUNING echoes, #2499 jq scope
resolution, Issue-8 CONDUCTOR gate) now pin the same invariants in their new
home: bin/gstack-skill-start / bin/gstack-skill-end file content for script
internals, the invocation fence + interpretation prose for render-side
behavior. No assertion deleted without a successor; live-execution tests
(routing probe, brain-sync jq) run against script bytes unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Garry Tan
2026-08-25 15:37:00 +00:00
co-authored by Claude Fable 5
parent eb1607aaf8
commit 17bebe33ab
9 changed files with 280 additions and 109 deletions
+24 -13
View File
@@ -3,12 +3,15 @@
*
* The telemetry consent copy promises a user's repo name is recorded locally
* only and stripped before any upload (scripts/resolvers/preamble/
* generate-telemetry-prompt.ts). Two producers write repo/branch identity into
* the local skill-usage.jsonl:
* generate-telemetry-prompt.ts). The producers that write repo/branch identity
* into the local skill-usage.jsonl (the preamble's inline bash moved into the
* skill-start/skill-end scripts in token-reduction Phase 1):
*
* - the preamble epilogue → "repo"
* (scripts/resolvers/preamble/generate-preamble-bash.ts)
* - gstack-telemetry-log → "_repo_slug", "_branch"
* - gstack-skill-start (skill_run event) → "repo"
* (bin/gstack-skill-start)
* - gstack-skill-end (completion event) → (no repo identity today,
* scanned so drift is caught) (bin/gstack-skill-end)
* - gstack-telemetry-log → "_repo_slug", "_branch"
* (bin/gstack-telemetry-log)
*
* gstack-telemetry-sync MUST strip every one of those fields before the remote
@@ -37,7 +40,8 @@ import path from 'path';
const ROOT = path.resolve(__dirname, '..');
const SYNC = path.join(ROOT, 'bin', 'gstack-telemetry-sync');
const PREAMBLE = path.join(ROOT, 'scripts', 'resolvers', 'preamble', 'generate-preamble-bash.ts');
const SKILL_START = path.join(ROOT, 'bin', 'gstack-skill-start');
const SKILL_END = path.join(ROOT, 'bin', 'gstack-skill-end');
const TEL_LOG = path.join(ROOT, 'bin', 'gstack-telemetry-log');
// Fields that identify the user's repo/branch. The promise is that NONE of
@@ -94,10 +98,16 @@ describe('telemetry no-repo-identity-egress invariant', () => {
// Repo-identity fields the producers emit into the synced file — computed
// once, asserted against BOTH strip paths (jq primary, sed fallback). Only
// emission lines that target the synced file (skill-usage.jsonl) count: the
// preamble appends directly; gstack-telemetry-log builds the synced event
// with a `printf '{"v":1,...` line into $JSONL_FILE (= skill-usage.jsonl).
const preambleSynced = fs
.readFileSync(PREAMBLE, 'utf-8')
// skill-start/skill-end scripts append directly (the former inline preamble
// bash); gstack-telemetry-log builds the synced event with a
// `printf '{"v":1,...` line into $JSONL_FILE (= skill-usage.jsonl). The
// timeline log carries "branch" but is local-only and never synced.
const skillStartSynced = fs
.readFileSync(SKILL_START, 'utf-8')
.split('\n')
.filter((l) => l.includes('skill-usage.jsonl'));
const skillEndSynced = fs
.readFileSync(SKILL_END, 'utf-8')
.split('\n')
.filter((l) => l.includes('skill-usage.jsonl'));
const telLogSynced = fs
@@ -105,7 +115,8 @@ describe('telemetry no-repo-identity-egress invariant', () => {
.split('\n')
.filter((l) => l.includes('"v":1') || l.includes('skill-usage'));
const emitted = new Set<string>([
...emittedRepoFields(preambleSynced),
...emittedRepoFields(skillStartSynced),
...emittedRepoFields(skillEndSynced),
...emittedRepoFields(telLogSynced),
]);
@@ -116,8 +127,8 @@ describe('telemetry no-repo-identity-egress invariant', () => {
});
test('coverage: every repo/branch field the producers emit into skill-usage.jsonl is stripped (sed fallback path)', () => {
// The preamble must emit "repo" — guards against the test silently passing
// because a regex stopped matching the producer.
// gstack-skill-start must emit "repo" — guards against the test silently
// passing because a regex stopped matching the producer.
expect(emitted.has('repo')).toBe(true);
for (const field of emitted) {
expect(