Skip to content

Commit 0e2e106

Browse files
committed
test(create-objectstack): converge the third GIT_* allowlist carrier onto gitFreeEnv()
The hand-maintained ten-name `GIT_*` location allowlist survived in one more file after the two spec carriers were converged. It is retired here the same way, so the repo carries one spelling of the strip and no transitional state. `REPO_READ_ENV` is now `gitFreeEnv()`. The blanket strip is strictly wider than the list it replaces and stays inside the boundary this file's header draws: it DELETES keys rather than pinning any to `/dev/null`, so it never sets `GIT_CONFIG_GLOBAL` and global/system config -- `safe.directory` with it -- stays open. Both children here are local reads against `cwd` (`ls-files` and `git grep`), so the transport settings the strip also removes are nothing either one needs. The `:42-54` prose is kept: it records why this carrier stops short of the fixture harnesses' `/dev/null` config pins. The import is a relative ES-module specifier that escapes the package, which forces two companion declarations -- `scripts/cross-package-test-inputs.mjs` and `turbo.json` -- so a change to the strip re-runs this package's suite instead of replaying a cached green over it. Measured before they landed: the gate named `scripts/git-env.mjs` and exited 1. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QCdUBjM47SxioST9z5Zwdf
1 parent 8271c81 commit 0e2e106

3 files changed

Lines changed: 42 additions & 17 deletions

File tree

‎packages/create-objectstack/src/template-consistency.test.ts‎

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { fileURLToPath } from 'node:url';
1414
import { syncObjectStackDeps } from './pkg-utils.js';
1515
import { copyDir, TEMPLATE_FILE_ALIASES } from './template-copy.js';
1616
import { TEMPLATES } from './template-registry.js';
17+
import { gitFreeEnv } from '../../../scripts/git-env.mjs';
1718
import { SKILLS_CATALOG, SKILLS_INSTALL_COMMAND } from './skills-install.js';
1819

1920
const pkgRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
@@ -52,26 +53,32 @@ const REGISTRY_SOURCE = fs.readFileSync(path.join(pkgRoot, 'src', 'index.ts'), '
5253
// read a checkout owned by another user inside a container. Closing it could
5354
// turn a passing read into `detected dubious ownership`, which is a
5455
// regression this file gets no isolation benefit in exchange for.
55-
const LEAKED_GIT_ENV = [
56-
'GIT_DIR',
57-
'GIT_WORK_TREE',
58-
'GIT_COMMON_DIR',
59-
'GIT_INDEX_FILE',
60-
'GIT_OBJECT_DIRECTORY',
61-
'GIT_ALTERNATE_OBJECT_DIRECTORIES',
62-
'GIT_NAMESPACE',
63-
'GIT_CEILING_DIRECTORIES',
64-
'GIT_TEMPLATE_DIR',
65-
'GIT_CONFIG',
66-
] as const;
56+
//
57+
// #16644 — the hand-maintained allowlist of ten location variables that used to
58+
// stand here is retired in favour of the blanket strip in `scripts/git-env.mjs`,
59+
// and it is not re-spelled anywhere in this file so that a census of the retired
60+
// shape does not match this paragraph. The reason the list goes rather than gets
61+
// one more entry: it had to be kept level with git's own list of location
62+
// variables, and its failure mode is that THE KEY IT MISSES IS THE KEY THAT
63+
// BITES. ⛔ One spelling in the repo, not two — no "either is fine" transition
64+
// state.
65+
//
66+
// `gitFreeEnv()` removes every `GIT_`-prefixed key, which is strictly wider than
67+
// the list it replaces and still inside the boundary drawn above. It DELETES
68+
// keys rather than pinning any of them to `/dev/null`, so it never sets
69+
// `GIT_CONFIG_GLOBAL`: global and system config stay open and `safe.directory`
70+
// with them, which is the whole of the concern in the bullet above — preserved,
71+
// and more strictly, because the deletion moves git toward its own defaults
72+
// instead of substituting an empty config file. The widening is free here for
73+
// the other reason the module's header names: both children below are LOCAL
74+
// reads — `ls-files` and `git grep` against `cwd` — so the transport settings
75+
// the strip also takes (`GIT_CONFIG_*` rewriting remotes, `GIT_SSL_*`) are
76+
// nothing either one needs. ⛔ A child that fetches, clones or pushes would not
77+
// be entitled to this environment.
6778

6879
/** The environment the repo-reading git calls below get: this process's, minus
6980
* every variable that could aim them at a different repository. */
70-
const REPO_READ_ENV: NodeJS.ProcessEnv = (() => {
71-
const env = { ...process.env };
72-
for (const key of LEAKED_GIT_ENV) delete env[key];
73-
return env;
74-
})();
81+
const REPO_READ_ENV: NodeJS.ProcessEnv = gitFreeEnv();
7582

7683
// ── Declared version surfaces, per bundled template (#9264) ─────────────────
7784
//

‎scripts/cross-package-test-inputs.mjs‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,23 @@ export const CROSS_PACKAGE_TEST_INPUTS = {
13931393
// with ERR_MODULE_NOT_FOUND), which is exactly the trigger radius this
13941394
// declaration exists to keep honest.
13951395
'scripts/invoked-as.mjs',
1396+
// The git-environment strip, IMPORTED by src/template-consistency.test.ts.
1397+
// That file's skills-catalog block asks git two questions whose answers ARE
1398+
// its verdict — `ls-files '*SKILL.md'` and a `git grep` over the
1399+
// customer-facing surfaces — and both run against the REAL checkout, so a
1400+
// `GIT_DIR` or `GIT_INDEX_FILE` inherited from a hook would make them answer
1401+
// for a DIFFERENT repository while `cwd` still reads as this one. The test
1402+
// used to spell a hand-maintained ten-name allowlist inline; `gitFreeEnv()`
1403+
// replaces it, which is the #16644 convergence onto one spelling.
1404+
//
1405+
// FORCED rather than chosen, and the same shape as the `.d.mts` pair above:
1406+
// the import is a relative ES-module specifier vitest RESOLVES AND LOADS at
1407+
// run time, so the module is a live input to this package's verdict, and an
1408+
// undeclared escaping import is a red gate by design. Measured on the
1409+
// conversion commit before this line existed — the gate printed
1410+
// `scripts/git-env.mjs (named in packages/create-objectstack/src/template-consistency.test.ts)`
1411+
// and exited 1.
1412+
'scripts/git-env.mjs',
13961413
'.github/workflows/scaffold-e2e.yml',
13971414
'packages/cli/src/commands/serve.ts',
13981415
'scripts/gen-sdui-manifest.sh',

‎turbo.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@
502502
"$TURBO_ROOT$/content/**",
503503
"$TURBO_ROOT$/scripts/sync-template-versions.mjs",
504504
"$TURBO_ROOT$/scripts/invoked-as.mjs",
505+
"$TURBO_ROOT$/scripts/git-env.mjs",
505506
"$TURBO_ROOT$/.github/workflows/scaffold-e2e.yml",
506507
"$TURBO_ROOT$/packages/cli/src/commands/serve.ts",
507508
"$TURBO_ROOT$/scripts/gen-sdui-manifest.sh",

0 commit comments

Comments
 (0)