') + ')', 'gi');
if (regex.test(text)) {
found = true;
var frag = document.createDocumentFragment();
var parts = text.split(regex);
parts.forEach(function(part, i) {
if (i % 2 === 0) {
frag.appendChild(document.createTextNode(part));
} else {
var span = document.createElement('span');
span.className = 'userscript-highlight';
span.textContent = part;
frag.appendChild(span);
}
});
node.parentNode.replaceChild(frag, node);
}
});
} else if (node.nodeType === 1 && node.childNodes) { // element
var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];
if (!skipTags.includes(node.tagName)) {
Array.from(node.childNodes).forEach(highlight);
}
}
}
highlight(document.body);
// Re-highlight on dynamic content
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(m) {
m.addedNodes.forEach(function(node) {
if (node.nodeType === 1 || node.nodeType === 3) highlight(node);
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); }
})();
(function(){
try {
var __m = "*";
var __re = new RegExp('^' + ".*" + ', 'i');
if (__m === '*' || __re.test(location.href)) {
// Strip utm_, fbclid, gclid, etc. from all links on page
(function() {
var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',
'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',
'ref', 'ref_src', 'source', 'medium', 'campaign'];
function cleanUrl(url) {
try {
var u = new URL(url, window.location.origin);
var changed = false;
trackingParams.forEach(function(p) {
if (u.searchParams.has(p)) {
u.searchParams.delete(p);
changed = true;
}
});
return changed ? u.toString() : url;
} catch (e) {
return url;
}
}
function cleanLinks() {
document.querySelectorAll('a[href]').forEach(function(a) {
var clean = cleanUrl(a.href);
if (clean !== a.href) a.href = clean;
});
}
cleanLinks();
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(m) {
m.addedNodes.forEach(function(node) {
if (node.nodeType === 1) {
if (node.tagName === 'A') cleanLinks();
node.querySelectorAll('a[href]').forEach(function(a) {
var clean = cleanUrl(a.href);
if (clean !== a.href) a.href = clean;
});
}
});
});
});
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); }
})();
(function(){
try {
var __m = "youtube.com";
var __re = new RegExp('^' + "youtube\\.com" + ', 'i');
if (__m === '*' || __re.test(location.href)) {
// Auto-enable theater mode on YouTube
(function() {
function tryTheater() {
var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]');
if (btn && !btn.classList.contains('activated')) {
btn.click();
}
}
// Try immediately
tryTheater();
// Try after navigation (SPA)
var lastUrl = location.href;
setInterval(function() {
if (location.href !== lastUrl) {
lastUrl = location.href;
setTimeout(tryTheater, 500);
}
}, 1000);
// Also try on player load
var observer = new MutationObserver(tryTheater);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); }
})();
(function(){
try {
var __m = "*";
var __re = new RegExp('^' + ".*" + ', 'i');
if (__m === '*' || __re.test(location.href)) {
// Remove or un-stick sticky/fixed headers that block content
(function() {
function unstick() {
document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) {
if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {
el.style.position = 'static';
el.style.top = 'auto';
el.style.zIndex = 'auto';
}
});
}
unstick();
var observer = new MutationObserver(unstick);
observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });
})();
}
} catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); }
})();
})();
test(core): pin that the legacy platform-admin deprecation latch dies with the process (L5) by os-steve · Pull Request #13666 · objectstack-ai/objectstack · GitHub
You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Part of #11975 — leg L5 of the #11663 platform-admin re-anchor.
This card is a verification-and-disposition slice, and its main output is the
measurement below, not the code. The entry half of the migration window was found already delivered by L2 and L4; the one discipline the card names that nothing
pinned is now pinned. One test file, no behaviour change.
What the card owed, and what was found
#11975 carries the migration window's discipline: derivation prefers env · a
detected legacy grant logs its deprecation pointer every boot · never a silent
dual-track. All three were measured against origin/main, not assumed.
1. Derivation prefers env — SATISFIED (precedence, not exclusion)
packages/core/src/security/resolve-authz-context.ts §6b-config is if (configConfersPlatformAdmin) { ... } else if (hasPlatformAdminGrant) { report }.
The config arm is evaluated first, confers standing, and pushes the declared
capability envelope from ADMIN_FULL_ACCESS_CAPABILITIES; the legacy arm is
reachable only when config does not confer.
⚠️ "Prefers" here means precedence inside the derivation, not exclusion: with
administrators declared, a caller who does not match still has their legacy row
honoured. That is the ruled shape — design §5 step 3, "Config-derived standing is added; the legacy grant read is still honoured. Nothing is revoked in this
step." Exclusion is the window's EXIT, and it belongs to #13515.
2. Every boot vs once per process — MEASURED, and it satisfies the card
The latch is a module-scope let legacyGrantPointerSaid in packages/core/src/security/platform-admin.ts. Measured over three fresh module
instances (the closest in-process stand-in for a boot): 1 line each, and two
calls inside one instance still produce 1. So "once per process" and "every boot"
coincide — nothing persists the suppression past the process, and a restarted
deployment is told again.
Two ways it differs from a literal per-detection line, both ruled by design P5
("logged once per process (not per request) naming the row, its holder and the
exact config line") and both disclosed in the message text itself:
a second boot inside ONE process is silent — deliberately pinned in plugin-security/src/bootstrap-platform-admin-walled-owner.test.ts, "EXACTLY ONE
line ... even across repeated bootstraps";
a second, distinct legacy holder is never named — the line says so: "Reported once
per process; further holders are not listed." Enumerating holders is the census's
job (design §5 step 7), not this pointer's.
3. Never a silent dual-track — NONE FOUND
Two detectors share one latch and cover both entry points: boot-side
(plugin-security/src/bootstrap-platform-admin.ts, walled) and request-side
(resolve-authz-context.ts, posture-independent). hasPlatformAdminGrant is
written in exactly two places and consumed once by derivePosture; a repo-wide
grep finds no third route to PLATFORM_ADMIN. The cross-request grants cache is
in-process and default-OFF, so it cannot carry standing across a boot without a
derivation having run. The only path where a legacy row confers with no line is the same caller also matching config, where standing no longer rests on the row
— already pinned in resolve-authz-context.platform-admin-config.test.ts.
The gap this PR fills
Every existing pin asserts suppression. None asserts that the suppression ends. A latch moved onto globalThis, or persisted to quiet the noise, turns
"once per process" into "once ever" and leaves all of them green — while a
deployment restarted onto the old anchor is never told again. That is the silent
dual-track the window exists to prevent, and it is precisely the half the card names
by name ("every boot").
So this PR adds one pin to packages/core/src/security/platform-admin.test.ts:
three fresh module instances must each emit exactly one line — not zero (a latch
that outlived the process) and not two (a pointer gone per-call).
Reverse verification. The pin was committed first, then platform-admin.ts's latch was mutated to a globalThis-keyed one. Mutation
confirmed on disk before measuring — HEAD blob c2abfe57, mutated blob 8e9478c3,
injected marker present 3x, original declaration count 0. Result: the new pin failed (expected [ +0, +0, +0 ] to deeply equal [ 1, 1, 1 ]) and the other 25
tests in the file stayed green — confirming this is the only pin covering the
every-boot half. Restored and verified by state: worktree blob back to c2abfe57,
marker count 0, git diff HEAD empty. No rebuild was needed on either leg — the
test imports ./platform-admin.js, a package-relative specifier vitest resolves to
source rather than through exports/dist.
Established here because #13515 is blocked on this card and needs exactly this
number:
@objectstack/plugin-security@17.2.0 (and @objectstack/core@17.2.0) is the
latest released tag, cut at e7d2cc67f on 2026-08-23.
L4 landed as b9972720f on 2026-08-31 — after that tag, so it is not in
17.2.0.
Its changeset .changeset/walled-bootstrap-stops-granting.md is still unconsumed
on main and declares "@objectstack/plugin-security": minor. No pending
changeset anywhere in .changeset/ declares a major.
L2 landed 2026-08-30, also after the tag, so it ships in the same release.
⇒ L4 ships in 17.3.0, and the exit may land no earlier than 17.4.0 — it must
not ride the 17.3.0 release train. Recorded on #13515.
Disposition
The window's entry is delivered and correctly disciplined. #11975's own acceptance
criterion also requires the exit on origin/main, which is #13515 and cannot land
before 17.4.0 — so this card's only live residue is that card. #13515 is not
addressed here.
Gate families re-derived from the actual diff with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, both sections: 22 path-derived + 6 convention-triggered (change kind "adds or edits a test file"). 23 ran green.
Two returned exit 3 = NOT MEASURED, each self-declared, neither a red: check-test-completeness.mjs (needs a saved test-run log; the family names it with
no argument) and check:dual-build-cjs-loads ("PREREQUISITE NOT MET ... this is
NOT a pass: nothing was measured" — needs a whole-workspace build).
check:type-check-coverage green. Its --re-measure half (check:type-check-debt)
needs the whole-workspace build and was not run locally; what was measured
instead is packages/core's own tsc --noEmit --listFiles: the new test file is in
the program (525 files, 1 match — packages/core sets exclude: []) and
contributes 0 of the package's 98 pre-existing errors, so this diff cannot move
the ratchet up. CI runs the re-measure.
check:nul-bytes green; grep -naP control-character self-scan over the edited
file finds nothing.
No changeset: the diff is one *.test.ts, and packages/core publishes only ["dist","README.md","CHANGELOG.md"], so nothing is released. Labelled skip-changeset.
Out-of-scope finding, filed separately
Measured while checking discipline 3, and not touched here: on a single-posture
rig — the DEFAULT posture — the request-side pointer fires for the first-user
promotion row and tells the operator their anchor "is removed in a later release",
which under ruled Choice 4A is not true for that rig. Filed unassigned; it bears on #13515's single carve-out clause.
Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.
What this run could not see
a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 967402a12d6c7f43361df68357e29bba93465e47 → packageMentionDocs.
35 checks at d0c912847, zero failures (successes + skips only). Notably Temporal Conformance (live PG + MySQL) is green here — the same job that failed on PR #13685 forty minutes later. That is independent corroboration of #13688's diagnosis: the sql-driver-13056 MySQL-cell tests are under-budgeted at vitest's default 5000ms and fail on runner contention, not on anything in a diff.
Fence
git merge-base origin/main d0c912847 = 5364d2e5e; the diff against it is one file, +34/-1 — packages/core/src/security/platform-admin.test.ts. Nothing else. (⚠️ A git diff against the PR's recorded base sha 967402a12 shows 16 files; that is main having moved, not scope creep. The merge-base is the reading.)
The pin does what the body claims
Read directly rather than taken from the report. Three vi.resetModules() + dynamic-import cycles, tworeportLegacyPlatformAdminGrant calls inside each, asserting linesPerBoot equals [1, 1, 1]. That single assertion is a two-sided trap, and the comment says so in terms:
0 catches a latch hardened past the process (moved onto globalThis, persisted, or held alive by the host) — the exact regression that leaves every existing pin green while a restarted deployment is never told again;
2 catches the pointer degrading to per-call.
The ⛔ Do not "fix" a red here by resetting the latch in the loop line is the right thing to write down: it forecloses the one repair that would make the pin vacuous.
The reverse verification is the real deliverable
The dev did not assert coverage — it measured it, with on-disk proof at both ends:
mutated platform-admin.ts's latch to a globalThis-keyed one, confirmed the mutation before measuring (HEAD blob c2abfe57 → mutated blob 8e9478c3, injected marker present 3×, original declaration count 0);
the new pin failed with expected [ +0, +0, +0 ] to deeply equal [ 1, 1, 1 ] — the 0 arm, exactly as designed;
the other 25 tests in the same file stayed green, which is what establishes this is the only pin covering the every-boot half rather than a duplicate;
restored and verified by state, not by intent: worktree blob back to c2abfe57, marker count 0, git diff HEAD empty.
That is the ablation pattern done to standard. An "I added a test" claim with no ablation would not have shown that the 25 siblings all stay green under the mutation — which is the whole justification for the card.
Discipline readings 1–3, and one correction I am adopting
The three claims #11975 owed were measured against origin/main, not assumed, and I accept them. One deserves to be quoted forward because it is the kind of thing that gets mis-summarised later:
⚠️ "Prefers" here means precedence inside the derivation, not exclusion: with administrators declared, a caller who does not match still has their legacy row honoured.
That is the ruled shape (design §5 step 3 — config standing is added, nothing is revoked in this step). Exclusion is the window's exit, and it is #13515's, not this card's. Anyone reading "derivation prefers env" as "the row stops working" would mis-scope #13515.
No changeset — correct, not an omission
The diff is one *.test.ts, and packages/core publishes only ["dist","README.md","CHANGELOG.md"], so nothing is released. skip-changeset is the right label and Check Changeset is green with it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #11975 — leg L5 of the #11663 platform-admin re-anchor.
This card is a verification-and-disposition slice, and its main output is the
measurement below, not the code. The entry half of the migration window was found
already delivered by L2 and L4; the one discipline the card names that nothing
pinned is now pinned. One test file, no behaviour change.
What the card owed, and what was found
#11975 carries the migration window's discipline: derivation prefers env · a
detected legacy grant logs its deprecation pointer every boot · never a silent
dual-track. All three were measured against
origin/main, not assumed.1. Derivation prefers env — SATISFIED (precedence, not exclusion)
packages/core/src/security/resolve-authz-context.ts§6b-config isif (configConfersPlatformAdmin) { ... } else if (hasPlatformAdminGrant) { report }.The config arm is evaluated first, confers standing, and pushes the declared
capability envelope from
ADMIN_FULL_ACCESS_CAPABILITIES; the legacy arm isreachable only when config does not confer.
administrators declared, a caller who does not match still has their legacy row
honoured. That is the ruled shape — design §5 step 3, "Config-derived standing is
added; the legacy grant read is still honoured. Nothing is revoked in this
step." Exclusion is the window's EXIT, and it belongs to #13515.
2. Every boot vs once per process — MEASURED, and it satisfies the card
The latch is a module-scope
let legacyGrantPointerSaidinpackages/core/src/security/platform-admin.ts. Measured over three fresh moduleinstances (the closest in-process stand-in for a boot): 1 line each, and two
calls inside one instance still produce 1. So "once per process" and "every boot"
coincide — nothing persists the suppression past the process, and a restarted
deployment is told again.
Two ways it differs from a literal per-detection line, both ruled by design P5
("logged once per process (not per request) naming the row, its holder and the
exact config line") and both disclosed in the message text itself:
plugin-security/src/bootstrap-platform-admin-walled-owner.test.ts, "EXACTLY ONEline ... even across repeated bootstraps";
per process; further holders are not listed." Enumerating holders is the census's
job (design §5 step 7), not this pointer's.
3. Never a silent dual-track — NONE FOUND
Two detectors share one latch and cover both entry points: boot-side
(
plugin-security/src/bootstrap-platform-admin.ts, walled) and request-side(
resolve-authz-context.ts, posture-independent).hasPlatformAdminGrantiswritten in exactly two places and consumed once by
derivePosture; a repo-widegrep finds no third route to
PLATFORM_ADMIN. The cross-request grants cache isin-process and default-OFF, so it cannot carry standing across a boot without a
derivation having run. The only path where a legacy row confers with no line is
the same caller also matching config, where standing no longer rests on the row
— already pinned in
resolve-authz-context.platform-admin-config.test.ts.The gap this PR fills
Every existing pin asserts suppression. None asserts that the suppression
ends. A latch moved onto
globalThis, or persisted to quiet the noise, turns"once per process" into "once ever" and leaves all of them green — while a
deployment restarted onto the old anchor is never told again. That is the silent
dual-track the window exists to prevent, and it is precisely the half the card names
by name ("every boot").
So this PR adds one pin to
packages/core/src/security/platform-admin.test.ts:three fresh module instances must each emit exactly one line — not zero (a latch
that outlived the process) and not two (a pointer gone per-call).
Reverse verification. The pin was committed first, then
platform-admin.ts's latch was mutated to aglobalThis-keyed one. Mutationconfirmed on disk before measuring — HEAD blob
c2abfe57, mutated blob8e9478c3,injected marker present 3x, original declaration count 0. Result: the new pin
failed (
expected [ +0, +0, +0 ] to deeply equal [ 1, 1, 1 ]) and the other 25tests in the file stayed green — confirming this is the only pin covering the
every-boot half. Restored and verified by state: worktree blob back to
c2abfe57,marker count 0,
git diff HEADempty. No rebuild was needed on either leg — thetest imports
./platform-admin.js, a package-relative specifier vitest resolves tosource rather than through
exports/dist.The minor boundary #13515 must honour
Established here because #13515 is blocked on this card and needs exactly this
number:
@objectstack/plugin-security@17.2.0(and@objectstack/core@17.2.0) is thelatest released tag, cut at
e7d2cc67fon 2026-08-23.b9972720fon 2026-08-31 — after that tag, so it is not in17.2.0.
.changeset/walled-bootstrap-stops-granting.mdis still unconsumedon
mainand declares"@objectstack/plugin-security": minor. No pendingchangeset anywhere in
.changeset/declares amajor.⇒ L4 ships in 17.3.0, and the exit may land no earlier than 17.4.0 — it must
not ride the 17.3.0 release train. Recorded on #13515.
Disposition
The window's entry is delivered and correctly disciplined. #11975's own acceptance
criterion also requires the exit on
origin/main, which is #13515 and cannot landbefore 17.4.0 — so this card's only live residue is that card. #13515 is not
addressed here.
Verification
Run at
d0c912847, the final commit.pnpm --filter @objectstack/core exec vitest run --maxWorkers=2 src/security/platform-admin.test.ts src/security/resolve-authz-context.platform-admin-config.test.ts src/security/admin-standing-surface.test.ts—Test Files 3 passed (3) · Tests 53 passed (53).node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, both sections: 22 path-derived + 6 convention-triggered (change kind "adds or edits a test file"). 23 ran green.check-test-completeness.mjs(needs a saved test-run log; the family names it withno argument) and
check:dual-build-cjs-loads("PREREQUISITE NOT MET ... this isNOT a pass: nothing was measured" — needs a whole-workspace build).
pnpm lint(eslint . --no-inline-config, whole repo, no narrowing) — exit 0.check:type-check-coveragegreen. Its--re-measurehalf (check:type-check-debt)needs the whole-workspace build and was not run locally; what was measured
instead is
packages/core's owntsc --noEmit --listFiles: the new test file is inthe program (525 files, 1 match —
packages/coresetsexclude: []) andcontributes 0 of the package's 98 pre-existing errors, so this diff cannot move
the ratchet up. CI runs the re-measure.
check:nul-bytesgreen;grep -naPcontrol-character self-scan over the editedfile finds nothing.
No changeset: the diff is one
*.test.ts, andpackages/corepublishes only["dist","README.md","CHANGELOG.md"], so nothing is released. Labelledskip-changeset.Out-of-scope finding, filed separately
Measured while checking discipline 3, and not touched here: on a
single-posturerig — the DEFAULT posture — the request-side pointer fires for the first-user
promotion row and tells the operator their anchor "is removed in a later release",
which under ruled Choice 4A is not true for that rig. Filed unassigned; it bears on
#13515's
singlecarve-out clause.Generated by Claude Code
Generated by Claude Code