Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
1da9f0c
Keep worldwide base surface continuous at every zoom
Occumed79 Jul 28, 2026
3f8883f
Keep base landcover visible from globe zoom
Occumed79 Jul 28, 2026
a3ea969
Guard continuous globe landcover
Occumed79 Jul 28, 2026
d0805fb
Validate one continuous physical surface across zooms
Occumed79 Jul 28, 2026
8bb9888
Validate base surface continuity across zoom thresholds
Occumed79 Jul 28, 2026
457e6f8
Validate every zoom level continuously
Occumed79 Jul 28, 2026
9640247
Run a full-range zoom sweep in CI
Occumed79 Jul 28, 2026
5d15102
Add tracked outward globe atmosphere bloom
Occumed79 Jul 28, 2026
52e25c9
Render a visible exterior atmosphere halo
Occumed79 Jul 28, 2026
947f198
Guard the tracked atmosphere bloom
Occumed79 Jul 28, 2026
8444975
Prove the atmosphere bloom in globe renders
Occumed79 Jul 28, 2026
3b45fcc
Harden PMTiles range fetching and circuit breaking
Occumed79 Jul 28, 2026
63f629f
Harden worldwide tile gateway failure handling
Occumed79 Jul 28, 2026
fb71744
Harden worldwide shard routing index
Occumed79 Jul 28, 2026
a737282
Add vector tile safety budgets
Occumed79 Jul 28, 2026
1f49eca
Add worldwide gateway chaos hardening tests
Occumed79 Jul 28, 2026
8e6d9a6
Run worldwide hardening checks in every build
Occumed79 Jul 28, 2026
ec3f1f4
Aggressively harden the production map server
Occumed79 Jul 28, 2026
8590603
Clean retry abort listeners and expose circuit behavior
Occumed79 Jul 28, 2026
dd64185
Exercise PMTiles circuit breaker in chaos tests
Occumed79 Jul 28, 2026
531ad52
Keep essential retry timers referenced
Occumed79 Jul 28, 2026
3717689
Align PMTiles integration guard with hardened continuous surface
Occumed79 Jul 28, 2026
1629d87
Add candidate HTTP hardening and concurrency gate
Occumed79 Jul 28, 2026
212236d
Run candidate HTTP hardening before visual sweeps
Occumed79 Jul 28, 2026
6f2ec6b
Add production dependency and lockfile security gate
Occumed79 Jul 28, 2026
5fc67b3
Validate every MVT payload before merge or overscale
Occumed79 Jul 28, 2026
cd5028f
Guard pre-merge and pre-overscale MVT validation
Occumed79 Jul 28, 2026
8c1ce47
Capture complete hardened build diagnostics
Occumed79 Jul 28, 2026
829a405
Install pinned native dependencies before hardened build
Occumed79 Jul 28, 2026
b6a1479
Validate the virtual tile route by behavior contract
Occumed79 Jul 28, 2026
c12ca8b
Allow canonical empty protobuf vector tiles
Occumed79 Jul 28, 2026
d0bb883
Keep worldwide landcover continuous through native surface zooms
Occumed79 Jul 28, 2026
f50ab1a
Strengthen the tracked exterior atmosphere bloom
Occumed79 Jul 28, 2026
f1d83c6
Make polygon and foundation validation exhaustive and forensic
Occumed79 Jul 28, 2026
d66b830
Stress every zoom across land ocean and antimeridian
Occumed79 Jul 28, 2026
9aff4b3
Make continuous motion validation exhaustive and forensic
Occumed79 Jul 28, 2026
3864ed9
Run every runtime hardening gate and preserve all diagnostics
Occumed79 Jul 28, 2026
7bb901e
Add sustained worldwide gateway soak validation
Occumed79 Jul 28, 2026
fe673c7
Require sustained worldwide gateway soak before browser validation
Occumed79 Jul 28, 2026
8966e9f
Lock continuous surface bloom and soak protections
Occumed79 Jul 28, 2026
fc359a8
Run continuous foundation lock in every hardened build
Occumed79 Jul 28, 2026
06e7763
Keep chaos and foundation locks as separate mandatory build gates
Occumed79 Jul 28, 2026
7086755
Restore the pinned MapLibre style-spec dependency
Occumed79 Jul 28, 2026
d0f957b
Keep the atmosphere bloom synchronized with every globe movement
Occumed79 Jul 28, 2026
1558726
Make continuous motion validation cycle-safe and exhaustive
Occumed79 Jul 28, 2026
6b156d5
Make full-range zoom validation cycle-safe and non-short-circuiting
Occumed79 Jul 28, 2026
3ea75ff
Run every polygon and atmosphere regression view before failing
Occumed79 Jul 28, 2026
f6c0d95
Apply documented continuous rendering contract
Occumed79 Jul 28, 2026
ffd9482
Run documented rendering contract last
Occumed79 Jul 28, 2026
05434c4
Lock documented source and layer zoom semantics
Occumed79 Jul 28, 2026
f2adbaa
Validate continuous bathymetry instead of cutoff
Occumed79 Jul 28, 2026
a197be1
Retain the complete zoom pyramid for reverse navigation
Occumed79 Jul 28, 2026
f3b05c8
Lock full zoom-pyramid retention into continuity checks
Occumed79 Jul 28, 2026
18739fc
Use source-idle and timer sampling for motion validation
Occumed79 Jul 28, 2026
41d8dab
Validate actual globe minimum with continuous timer sampling
Occumed79 Jul 28, 2026
7ca5686
Force bathymetry into every native surface zoom
Occumed79 Jul 28, 2026
ab3b4b7
Lock low-zoom depth and documented sampling behavior
Occumed79 Jul 28, 2026
7f85130
Accept full zoom-pyramid browser retention
Occumed79 Jul 28, 2026
7c1c410
Validate full browser zoom-pyramid retention
Occumed79 Jul 28, 2026
3b748ca
Serve navigation archives from local disk
Occumed79 Jul 28, 2026
dfe1e4d
Require localized navigation assets in production
Occumed79 Jul 28, 2026
b8e6265
Prebuild coarse navigation tiles through zoom 6
Occumed79 Jul 28, 2026
faaaed0
Fix continuous zoom validation instrumentation
Occumed79 Jul 28, 2026
26ee960
placeholder
Occumed79 Jul 28, 2026
bc376f8
Create Neon integration anchor
Occumed79 Jul 28, 2026
dab64f2
Implement durable Neon navigation cache
Occumed79 Jul 28, 2026
751ee14
Wire persistent navigation cache into tile gateway
Occumed79 Jul 28, 2026
b102596
Connect Neon cache to production tile server
Occumed79 Jul 28, 2026
f8ca69b
Add Postgres client for Neon navigation cache
Occumed79 Jul 28, 2026
2efd88b
Add Neon navigation cache unit guard
Occumed79 Jul 28, 2026
74506e0
Document Neon navigation cache configuration
Occumed79 Jul 28, 2026
df20464
Verify memory-first Neon cache gateway flow
Occumed79 Jul 28, 2026
51842f8
Run focused Neon cache finalization
Occumed79 Jul 28, 2026
be74321
Use Neon HTTP SQL for durable navigation cache
Occumed79 Jul 28, 2026
6d1b43a
Keep Neon cache dependency-free
Occumed79 Jul 28, 2026
94ed983
Remove temporary Neon finalization workflow
Occumed79 Jul 28, 2026
27475bc
Remove temporary Neon integration anchor
Occumed79 Jul 28, 2026
59f5ee1
Test Neon HTTP cache transport and gateway flow
Occumed79 Jul 28, 2026
40f266b
Cap shared-project Neon cache storage safely
Occumed79 Jul 28, 2026
a7ee9b2
Document safe shared-project Neon cache limit
Occumed79 Jul 28, 2026
7ed506e
Fix Neon cache gateway guard variable
Occumed79 Jul 28, 2026
fbb0d11
Restore independent Neon project cache capacity
Occumed79 Jul 28, 2026
a4f45ef
Document independent Neon project cache capacity
Occumed79 Jul 28, 2026
df0efe4
Update continuity lock for lightweight validation sampling
Occumed79 Jul 28, 2026
71aa755
Fix continuous base surface retention
Occumed79 Jul 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/validate-continuous-zoom.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,16 @@ jobs:
OCCUMED_PREVIEW_OUTPUT=continuous-motion/results \
node scripts/validate-continuous-zoom.mjs

OCCUMED_PREVIEW_OUTPUT=continuous-motion/all-zoom-levels \
node scripts/validate-all-zoom-levels.mjs

- uses: actions/upload-artifact@v4
if: always()
with:
name: continuous-zoom-${{ github.sha }}
path: |
continuous-motion/results
continuous-motion/all-zoom-levels
continuous-motion/server.log
dist/virtual-assets/occumed-world-overview.pmtiles
if-no-files-found: error
Expand Down
3 changes: 2 additions & 1 deletion scripts/apply-schema-parity.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ water.metadata = {

const landcover = runtime.layers.find((layer) => layer.id === 'landcover');
if (!landcover) throw new Error('The exported landcover layer is missing from the runtime style.');
landcover.minzoom = 0;
landcover.paint ||= {};
landcover.paint['fill-opacity'] = [
'interpolate',
Expand All @@ -190,7 +191,7 @@ landcover.paint['fill-opacity'] = [
];
landcover.metadata = {
...(landcover.metadata || {}),
'occumed:purpose': 'strong exported vegetation hierarchy over open landcover data'
'occumed:purpose': 'continuous worldwide vegetation foundation with regional detail added above it'
};

runtime.metadata = {
Expand Down
85 changes: 72 additions & 13 deletions scripts/capture-polygon-regression.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,28 @@ try {
{ timeout: 90_000 }
);

const continuityZooms = [1.65, 2.43, 3.5, 5.5, 6.5];
const views = [
{ name: 'north-america-z2', center: [-102, 36], zoom: 2.43 },
{ name: 'central-pacific-z2', center: [175, 7], zoom: 2.43 },
{ name: 'australia-z2', center: [135, -25], zoom: 2.43 },
{ name: 'asia-pacific-z2', center: [118, 22], zoom: 2.43 },
{ name: 'africa-europe-z2', center: [20, 20], zoom: 2.43 },
{ name: 'world-north-america-z1', center: [-100, 25], zoom: 1.65 }
{ name: 'north-america-z2', center: [-102, 36], zoom: 2.43, requiresAtmosphereBloom: true },
{ name: 'central-pacific-z2', center: [175, 7], zoom: 2.43, requiresAtmosphereBloom: true },
{ name: 'australia-z2', center: [135, -25], zoom: 2.43, requiresAtmosphereBloom: true },
{ name: 'asia-pacific-z2', center: [118, 22], zoom: 2.43, requiresAtmosphereBloom: true },
{ name: 'africa-europe-z2', center: [20, 20], zoom: 2.43, requiresAtmosphereBloom: true },
{ name: 'world-north-america-z1', center: [-100, 25], zoom: 1.65, requiresAtmosphereBloom: true },
...continuityZooms.map((zoom) => ({
name: `amazon-z${String(zoom).replace('.', '-')}`,
center: [-60, -8],
zoom,
requiredSourceLayers: ['land', 'landcover'],
requiredRenderedLayers: ['land', 'landcover']
})),
...continuityZooms.map((zoom) => ({
name: `pacific-depth-z${String(zoom).replace('.', '-')}`,
center: [-140, 0],
zoom,
requiredSourceLayers: ['depth'],
requiredRenderedLayers: ['depth']
}))
];
const results = {};

Expand Down Expand Up @@ -87,23 +102,42 @@ try {
const features = map
.queryRenderedFeatures()
.filter((feature) => feature.source === 'occumed-open');
const sourceLayerCounts = {};
const renderedSourceLayerCounts = {};
const styleLayerCounts = {};
for (const feature of features) {
const sourceLayer = feature.sourceLayer || 'unknown';
const styleLayer = feature.layer?.id || 'unknown';
sourceLayerCounts[sourceLayer] = (sourceLayerCounts[sourceLayer] || 0) + 1;
renderedSourceLayerCounts[sourceLayer] = (renderedSourceLayerCounts[sourceLayer] || 0) + 1;
styleLayerCounts[styleLayer] = (styleLayerCounts[styleLayer] || 0) + 1;
}
const sourceFeatureCounts = Object.fromEntries(
['land', 'landcover', 'depth'].map((sourceLayer) => [
sourceLayer,
map.querySourceFeatures('occumed-open', { sourceLayer }).length
])
);
const bloom = document.querySelector('.occumed-atmosphere-bloom');
const bloomStyle = bloom ? getComputedStyle(bloom) : null;
const bloomRect = bloom?.getBoundingClientRect() || null;
return {
center: map.getCenter().toArray(),
zoom: map.getZoom(),
source,
sourceIsPermanent:
!source?.url && JSON.stringify(source?.tiles || []) === JSON.stringify([expectedTemplate]),
renderedFeatureCount: features.length,
sourceLayerCounts,
styleLayerCounts
renderedSourceLayerCounts,
sourceFeatureCounts,
styleLayerCounts,
atmosphereBloom: {
exists: Boolean(bloom),
hidden: Boolean(bloom?.hidden),
opacity: Number(bloomStyle?.opacity || 0),
filter: bloomStyle?.filter || 'none',
mixBlendMode: bloomStyle?.mixBlendMode || 'normal',
width: bloomRect?.width || 0,
height: bloomRect?.height || 0
}
};
}, expectedTemplate);

Expand All @@ -113,6 +147,28 @@ try {
if (diagnostics.renderedFeatureCount <= 0) {
throw new Error(`${view.name} rendered no worldwide vector features.`);
}
for (const sourceLayer of view.requiredSourceLayers || []) {
if ((diagnostics.sourceFeatureCounts[sourceLayer] || 0) <= 0) {
throw new Error(`${view.name} lost the ${sourceLayer} source layer at zoom ${view.zoom}.`);
}
}
for (const sourceLayer of view.requiredRenderedLayers || []) {
if ((diagnostics.renderedSourceLayerCounts[sourceLayer] || 0) <= 0) {
throw new Error(`${view.name} stopped rendering the ${sourceLayer} foundation at zoom ${view.zoom}.`);
}
}
if (view.requiresAtmosphereBloom) {
const bloom = diagnostics.atmosphereBloom;
if (!bloom.exists || bloom.hidden || bloom.opacity < 0.95) {
throw new Error(`${view.name} does not show the full-strength globe atmosphere bloom.`);
}
if (bloom.filter === 'none' || bloom.mixBlendMode !== 'screen') {
throw new Error(`${view.name} has a hard rim instead of the luminous white-blue bloom.`);
}
if (bloom.width < 150 || Math.abs(bloom.width - bloom.height) > 1) {
throw new Error(`${view.name} atmosphere bloom does not track the rendered globe.`);
}
}

const screenshot = await page.screenshot({
path: path.join(outputDir, `${view.name}.png`),
Expand All @@ -127,8 +183,9 @@ try {
const report = {
generatedAt: new Date().toISOString(),
origin,
mode: 'rebuilt-overview-polygon-regression',
mode: 'rebuilt-overview-polygon-layer-continuity-and-atmosphere-regression',
expectedTemplate,
continuityZooms,
results,
pageErrors,
networkFailures,
Expand All @@ -145,14 +202,16 @@ try {
);

if (!report.passed) {
throw new Error(`Polygon regression validation failed: ${JSON.stringify({
throw new Error(`Polygon, layer continuity, and atmosphere validation failed: ${JSON.stringify({
pageErrors,
networkFailures,
externalVectorRequests: report.externalVectorRequests
})}`);
}

console.log(`Rendered ${views.length} rebuilt-overview globe views without browser or network errors.`);
console.log(
`Rendered ${views.length} rebuilt-overview views with continuous physical layers and a tracked exterior atmosphere bloom.`
);
} finally {
await browser.close();
}
5 changes: 4 additions & 1 deletion scripts/check-cartography-parity.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ const landcover = layer('landcover');
if (!Array.isArray(landcover?.paint?.['fill-opacity'])) {
fail('The landcover layer must preserve the strong green low-zoom hierarchy.');
}
if (Number(landcover?.minzoom || 0) !== 0) {
fail('The foundational landcover layer must remain visible from globe zoom instead of switching on later.');
}

const roadLayers = runtime.layers.filter(
(candidate) =>
Expand Down Expand Up @@ -125,5 +128,5 @@ if (failures.length) {
}

console.log(
`Cartography parity validated: ${roadLayers.length} road layers, ${symbolLayers.length} symbol layers, normalized landuse, place hierarchy, and overlay isolation.`
`Cartography parity validated: ${roadLayers.length} road layers, ${symbolLayers.length} symbol layers, continuous globe landcover, normalized landuse, place hierarchy, and overlay isolation.`
);
18 changes: 14 additions & 4 deletions scripts/check-photo-reference.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { fileURLToPath } from 'node:url';

const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const runtimePath = path.join(root, 'public/style/occumed-open.json');
const runtime = JSON.parse(await fs.readFile(runtimePath, 'utf8'));
const [runtime, mapHelper, appCss] = await Promise.all([
fs.readFile(runtimePath, 'utf8').then(JSON.parse),
fs.readFile(path.join(root, 'src/occumed-map.js'), 'utf8'),
fs.readFile(path.join(root, 'src/styles.css'), 'utf8')
]);

function assert(condition, message) {
if (!condition) throw new Error(message);
Expand Down Expand Up @@ -47,13 +51,19 @@ assert(
);
assert(
runtime.sky?.['fog-color'] === 'rgba(184, 230, 255, 0.14)',
'The cool-blue outer atmosphere bloom is missing.'
'The cool-blue edge atmosphere is missing.'
);
assert(runtime.sky?.['fog-ground-blend'] === 0, 'Ground fog must remain disabled.');
assert(runtime.sky?.['horizon-fog-blend'] === 0.08, 'The narrow edge bloom strength changed.');
assert(runtime.sky?.['horizon-fog-blend'] === 0.08, 'The narrow edge atmosphere strength changed.');
assert(!runtime.light, 'Directional light must not be reintroduced.');
assert(!runtime.fog, 'Mapbox fog must not be copied into the MapLibre runtime.');
assert(runtime.metadata?.['occumed:atmosphere-edge-only'] === true, 'The edge-only atmosphere protection marker is missing.');
assert(mapHelper.includes('installOccumedAtmosphereBloom(map)'), 'The tracked exterior globe bloom is not installed.');
assert(mapHelper.includes('resolveGlobeRadius'), 'The atmosphere bloom no longer follows the rendered globe radius.');
assert(mapHelper.includes('BLOOM_FADE_END_ZOOM'), 'The atmosphere bloom does not fade before regional detail.');
assert(appCss.includes('.occumed-atmosphere-bloom'), 'The exterior atmosphere bloom styling is missing.');
assert(appCss.includes('drop-shadow(0 0 30px'), 'The atmosphere is only a hard rim and no longer has a visible outer bloom.');
assert(appCss.includes('mix-blend-mode: screen'), 'The white-blue atmosphere bloom no longer composites luminously.');

assert(layer('land')?.paint?.['background-color'] === '#79BCEC', 'The supplied Studio ocean blue changed.');
assert(layer('occumed-land-surface')?.paint?.['fill-color'] === '#E0E0D1', 'The supplied Studio land base changed.');
Expand Down Expand Up @@ -139,4 +149,4 @@ assert(!/mapbox:\/\//i.test(runtime.sprite || ''), 'Runtime sprite must not use
assert(!/api\.mapbox\.com/i.test(runtime.glyphs || ''), 'Runtime glyphs must not use Mapbox.');
assert(runtime.metadata?.['occumed:mapbox-runtime-dependency'] === false, 'No-Mapbox dependency marker is missing.');

console.log(`Reference guard passed: supplied Studio land and water, narrow edge-only atmosphere, high-DPI vector clarity, and ${allColors.size} distinct colors.`);
console.log(`Reference guard passed: supplied Studio land and water, narrow rim plus tracked outward atmosphere bloom, high-DPI vector clarity, and ${allColors.size} distinct colors.`);
72 changes: 44 additions & 28 deletions scripts/check-world-tile-gateway.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -134,32 +134,44 @@ const surface = tile({
]
}
});
const overscaled = inspectVectorTile(overscaleVectorLayer(surface, {
layerName: 'land',
sourceZoom: 10,
targetZoom: 16,
targetX: 32768,
targetY: 32768
}));
expect(overscaled.land?.featureCount === 1, 'The worldwide land surface cannot overscale through max zoom.');
for (const bounds of overscaled.land?.bounds || []) {
const continuousSurfaceLayers = ['land', 'landcover', 'depth'];
const overscaledSurface = inspectVectorTile(
mergeVectorTiles(
continuousSurfaceLayers.map((layerName) =>
overscaleVectorLayer(surface, {
layerName,
sourceZoom: 10,
targetZoom: 16,
targetX: 32768,
targetY: 32768
})
)
)
);
for (const layerName of continuousSurfaceLayers) {
expect(
bounds && bounds.minX >= 0 && bounds.minY >= 0 && bounds.maxX <= 4096 && bounds.maxY <= 4096,
'Overscaled land geometry escaped the requested child tile.'
overscaledSurface[layerName]?.featureCount === 1,
`The worldwide ${layerName} surface cannot overscale through max zoom.`
);
for (const bounds of overscaledSurface[layerName]?.bounds || []) {
expect(
bounds && bounds.minX >= 0 && bounds.minY >= 0 && bounds.maxX <= 4096 && bounds.maxY <= 4096,
`Overscaled ${layerName} geometry escaped the requested child tile.`
);
}
}
const physicalLandMask = inspectVectorTile(
mergeVectorTiles([surface], { includeLayers: ['land'] })
const physicalSurface = inspectVectorTile(
mergeVectorTiles([surface], { includeLayers: continuousSurfaceLayers })
);
expect(physicalLandMask.land?.featureCount === 1, 'The physical surface lost its land layer.');
expect(!physicalLandMask.landcover, 'The physical surface still overlays generalized landcover on regional detail.');
expect(!physicalLandMask.depth, 'The physical surface still overlays generalized bathymetry on regional detail.');
const cartographyWithoutLand = inspectVectorTile(
mergeVectorTiles([surface], { excludeLayers: ['land'] })
expect(physicalSurface.land?.featureCount === 1, 'The physical surface lost its land layer.');
expect(physicalSurface.landcover?.featureCount === 1, 'The physical surface lost continuous landcover.');
expect(physicalSurface.depth?.featureCount === 1, 'The physical surface lost continuous bathymetry.');
const cartographyWithoutSurface = inspectVectorTile(
mergeVectorTiles([surface], { excludeLayers: continuousSurfaceLayers })
);
expect(!cartographyWithoutLand.land, 'The duplicate basemap land layer was not excluded.');
expect(cartographyWithoutLand.landcover?.featureCount === 1, 'Excluding land removed unrelated cartography.');
expect(cartographyWithoutLand.depth?.featureCount === 1, 'Excluding land removed bathymetry.');
expect(!cartographyWithoutSurface.land, 'The duplicate basemap land layer was not excluded.');
expect(!cartographyWithoutSurface.landcover, 'The duplicate basemap landcover layer was not excluded.');
expect(!cartographyWithoutSurface.depth, 'The duplicate basemap bathymetry layer was not excluded.');

const normalizedProperties = normalizeMvtProperties({
safeRank: 4,
Expand Down Expand Up @@ -256,16 +268,20 @@ expect(
'A missing overview enrichment can still reject the complete worldwide tile.'
);
expect(
gateway.includes("includeLayers: ['land']"),
'The gateway does not isolate the continuous physical surface to the land mask.'
gateway.includes("const CONTINUOUS_SURFACE_LAYERS = Object.freeze(['land', 'landcover', 'depth'])"),
'The gateway does not define one authoritative set of foundational surface layers.'
);
expect(
gateway.includes('includeLayers: CONTINUOUS_SURFACE_LAYERS'),
'The gateway does not retain land, landcover, and bathymetry from the physical surface.'
);
expect(
gateway.includes("excludeLayers: ['land']"),
'The gateway can still merge duplicate land masks from the surface and basemap.'
gateway.includes('excludeLayers: CONTINUOUS_SURFACE_LAYERS'),
'The overview or regional archives can still replace the foundational surface layers.'
);
expect(
!gateway.includes("includeLayers: ['land', 'landcover', 'depth']"),
'The gateway still overlays generalized landcover and bathymetry on regional detail.'
gateway.includes('CONTINUOUS_SURFACE_LAYERS.map'),
'All foundational surface layers are not overscaled continuously through maximum zoom.'
);
expect(manifestBuilder.includes('version: 2'), 'The server-only routing manifest is not version 2.');
expect(
Expand All @@ -287,4 +303,4 @@ if (failures.length) {
process.exit(1);
}

console.log('Virtual worldwide tileset validated: one permanent source, safe polygon merging, clipped surface overscaling, one land mask, antimeridian routing, parent-tile retention, caching, and no browser-visible shards.');
console.log('Virtual worldwide tileset validated: one permanent source, one continuous land/landcover/depth foundation at every zoom, safe polygon merging, clipped overscaling, antimeridian routing, parent-tile retention, caching, and no browser-visible shards.');
Loading
Loading