ci(upstream-merge): default-to-ours; remove prefer_theirs usage; dynamic cleanup for reintroduced crates; smarter purge; agent autonomy

This commit is contained in:
James Peter
2025-09-07 19:36:08 +10:00
parent 283dad2afe
commit b5266c7cdb
3 changed files with 82 additions and 10 deletions
+1 -7
View File
@@ -8,13 +8,7 @@
"README.md",
"CHANGELOG.md"
],
"prefer_theirs_globs": [
"codex-rs/core/**",
"codex-rs/common/**",
"codex-rs/protocol/**",
"codex-rs/exec/**",
"codex-rs/file-search/**"
],
"prefer_theirs_globs": [],
"purge_globs": [
".github/codex-cli-*.png",
".github/codex-cli-*.jpg",
+16 -3
View File
@@ -195,11 +195,11 @@ jobs:
2) Ensure remote `upstream` points to the UPSTREAM_REPO in Context. Fetch origin and upstream.
3) Re-create branch MERGE_BRANCH from origin/DEFAULT_BRANCH.
4) Merge upstream/UPSTREAM_BRANCH using `--no-commit`.
- Use the <policy> JSON for prefer_ours_globs / prefer_theirs_globs / purge_globs.
- Use the <policy> JSON for prefer_ours_globs and purge_globs (prefer_theirs_globs is intentionally empty).
- Keep ours by default. Do NOT attempt to realign or reintroduce crates/dirs we removed locally.
- For files matching prefer_ours_globs: keep ours; if upstream added new files under these globs that we don’t have, prefer deletion.
- For files matching prefer_theirs_globs: prefer theirs.
- For any path listed in purge_globs: ensure it remains deleted if upstream reintroduced it.
- For everything else, default to ours unless the change is a clear, trivial improvement (typos/docs) that doesn’t conflict with our direction.
- Only adopt upstream when the change is trivial and clearly safe (typos, comments) and outside protected areas; otherwise keep ours.
5) Stage and commit with a conventional message and short build status.
6) Run ./build-fast.sh (warnings treated as failures). Apply minimal safe fixes only.
7) Write MERGE_REPORT.md (Incorporated / Dropped / Other changes) summarizing choices.
@@ -258,6 +258,19 @@ jobs:
files=$(git ls-files -- "$d/**" || true)
if [ -n "$files" ]; then echo "$files" | xargs -r git rm -f --; removed=true; fi
done
# Drop any codex-rs/<crate> directories that do not exist on the default branch (we removed/renamed them locally)
DEF_REF="origin/${DEFAULT_BRANCH}"
# Collect crate dirs on default and on current worktree
mapfile -t default_crates < <(git ls-tree -r --name-only "$DEF_REF" | awk -F'/' '/^codex-rs\//{print $1"/"$2}' | sort -u)
mapfile -t branch_crates < <(git ls-files | awk -F'/' '/^codex-rs\//{print $1"/"$2}' | sort -u)
for c in "${branch_crates[@]}"; do
keep=0
for d in "${default_crates[@]}"; do [ "$c" = "$d" ] && keep=1 && break; done
if [ $keep -eq 0 ]; then
files=$(git ls-files -- "$c/**" || true)
if [ -n "$files" ]; then echo "$files" | xargs -r git rm -f --; removed=true; fi
fi
done
# Apply purge_globs and perma_removed_paths from merge-policy.json when present
if command -v jq >/dev/null 2>&1 && [ -f ".github/merge-policy.json" ]; then
mapfile -t purges < <(jq -r '.purge_globs[]? // empty' .github/merge-policy.json 2>/dev/null || true)
+65
View File
@@ -414,6 +414,71 @@ impl Page {
}
} catch (e) { /* swallow */ }
// 5) Stealth: reduce headless/automation signals for basic anti-bot checks
try {
// webdriver: undefined
try { Object.defineProperty(Navigator.prototype, 'webdriver', { get: () => undefined }); } catch(_) {}
// languages
try {
const langs = ['en-US','en'];
Object.defineProperty(Navigator.prototype, 'languages', { get: () => langs.slice() });
Object.defineProperty(Navigator.prototype, 'language', { get: () => 'en-US' });
} catch(_) {}
// plugins & mimeTypes
try {
const fakePlugin = { name: 'Chrome PDF Plugin', filename: 'internal-pdf-viewer', description: 'Portable Document Format' };
const arrLike = (len) => ({ length: len, item(i){ return this[i]; } });
const plugins = arrLike(1); plugins[0] = fakePlugin;
const mimes = arrLike(2); mimes[0] = { type: 'application/pdf', suffixes: 'pdf', description: 'Portable Document Format' }; mimes[1] = { type: 'application/x-google-chrome-pdf', suffixes: 'pdf', description: 'Portable Document Format' };
Object.defineProperty(Navigator.prototype, 'plugins', { get: () => plugins });
Object.defineProperty(Navigator.prototype, 'mimeTypes', { get: () => mimes });
} catch(_) {}
// hardwareConcurrency & deviceMemory
try { Object.defineProperty(Navigator.prototype, 'hardwareConcurrency', { get: () => 8 }); } catch(_) {}
try { Object.defineProperty(Navigator.prototype, 'deviceMemory', { get: () => 8 }); } catch(_) {}
// permissions.query
try {
const orig = navigator.permissions && navigator.permissions.query ? navigator.permissions.query.bind(navigator.permissions) : null;
if (orig) {
navigator.permissions.query = function(p){
if (p && p.name === 'notifications') { return Promise.resolve({ state: 'granted' }); }
return orig(p);
}
}
} catch(_) {}
// WebGL vendor/renderer
try {
const spoof = (proto) => {
const orig = proto.getParameter;
Object.defineProperty(proto, 'getParameter', { value: function(p){
const UNMASKED_VENDOR_WEBGL = 0x9245; // WEBGL_debug_renderer_info
const UNMASKED_RENDERER_WEBGL = 0x9246;
if (p === UNMASKED_VENDOR_WEBGL) return 'Apple Inc.';
if (p === UNMASKED_RENDERER_WEBGL) return 'Apple M2';
return orig.apply(this, arguments);
}});
};
if (window.WebGLRenderingContext) spoof(WebGLRenderingContext.prototype);
if (window.WebGL2RenderingContext) spoof(WebGL2RenderingContext.prototype);
} catch(_) {}
// userAgentData (hints)
try {
if (!('userAgentData' in navigator)) {
Object.defineProperty(Navigator.prototype, 'userAgentData', { get: () => ({
brands: [ { brand: 'Chromium', version: '128' }, { brand: 'Google Chrome', version: '128' } ],
mobile: false,
platform: navigator.platform || 'macOS'
})});
}
} catch(_) {}
} catch(_) { /* ignore */ }
// 4) No cursor bootstrap here; full cursor is injected by runtime ensure_virtual_cursor
})();
"#;