aboutsummaryrefslogtreecommitdiff
path: root/downloads
diff options
context:
space:
mode:
Diffstat (limited to 'downloads')
-rw-r--r--downloads/CopyShader.js47
-rw-r--r--downloads/EffectComposer.js284
-rw-r--r--downloads/GLTFLoader.js3629
-rw-r--r--downloads/LuminosityHighPassShader.js71
-rw-r--r--downloads/RenderPass.js74
-rw-r--r--downloads/ShaderPass.js63
-rw-r--r--downloads/TransformControls.js1471
-rw-r--r--downloads/UnrealBloomPass.js366
-rw-r--r--downloads/dashboard.html643
-rw-r--r--downloads/evolution_plan/gunes-uygarligi-gercekci.html197
-rw-r--r--downloads/evolution_plan/gunes-uygarligi-newos4.html135
-rw-r--r--downloads/evolution_plan/gunes-uygarligi-sistem.html403
-rw-r--r--downloads/evolution_plan/presentation.html812
-rw-r--r--downloads/evolution_plan/system_review.html829
-rw-r--r--downloads/gunes-uygarligi.html1379
-rw-r--r--downloads/gunes-uygarligi/makale.html877
-rw-r--r--downloads/kb.html481
-rw-r--r--downloads/memory/newos-architecture-3d.html612
-rw-r--r--downloads/memory/release-arc-3d.html384
-rw-r--r--downloads/system-analysis-report.html556
-rw-r--r--downloads/system-review-v4.6.00.html603
-rw-r--r--downloads/system-review-v4.6.02.html767
-rw-r--r--downloads/system/program-specs.html265
-rw-r--r--downloads/system/research-self-improving-ai-2025-2026.html716
-rw-r--r--downloads/system/roadmap.html243
-rw-r--r--downloads/system/system-review-v4.6.00.html603
-rw-r--r--downloads/system/system-review-v4.6.02-public.html850
-rw-r--r--downloads/system/system-review-v4.6.02.html767
-rw-r--r--downloads/webX11AI_usecases.html1006
29 files changed, 19133 insertions, 0 deletions
diff --git a/downloads/CopyShader.js b/downloads/CopyShader.js
new file mode 100644
index 0000000..2e89bee
--- /dev/null
+++ b/downloads/CopyShader.js
@@ -0,0 +1,47 @@
+( function () {
+
+ /**
+ * Full-screen textured quad shader
+ */
+ var CopyShader = {
+ uniforms: {
+ 'tDiffuse': {
+ value: null
+ },
+ 'opacity': {
+ value: 1.0
+ }
+ },
+ vertexShader:
+ /* glsl */
+ `
+
+ varying vec2 vUv;
+
+ void main() {
+
+ vUv = uv;
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+ }`,
+ fragmentShader:
+ /* glsl */
+ `
+
+ uniform float opacity;
+
+ uniform sampler2D tDiffuse;
+
+ varying vec2 vUv;
+
+ void main() {
+
+ vec4 texel = texture2D( tDiffuse, vUv );
+ gl_FragColor = opacity * texel;
+
+ }`
+ };
+
+ THREE.CopyShader = CopyShader;
+
+} )();
diff --git a/downloads/EffectComposer.js b/downloads/EffectComposer.js
new file mode 100644
index 0000000..e7054ca
--- /dev/null
+++ b/downloads/EffectComposer.js
@@ -0,0 +1,284 @@
+( function () {
+
+ class EffectComposer {
+
+ constructor( renderer, renderTarget ) {
+
+ this.renderer = renderer;
+
+ if ( renderTarget === undefined ) {
+
+ const parameters = {
+ minFilter: THREE.LinearFilter,
+ magFilter: THREE.LinearFilter,
+ format: THREE.RGBAFormat
+ };
+ const size = renderer.getSize( new THREE.Vector2() );
+ this._pixelRatio = renderer.getPixelRatio();
+ this._width = size.width;
+ this._height = size.height;
+ renderTarget = new THREE.WebGLRenderTarget( this._width * this._pixelRatio, this._height * this._pixelRatio, parameters );
+ renderTarget.texture.name = 'EffectComposer.rt1';
+
+ } else {
+
+ this._pixelRatio = 1;
+ this._width = renderTarget.width;
+ this._height = renderTarget.height;
+
+ }
+
+ this.renderTarget1 = renderTarget;
+ this.renderTarget2 = renderTarget.clone();
+ this.renderTarget2.texture.name = 'EffectComposer.rt2';
+ this.writeBuffer = this.renderTarget1;
+ this.readBuffer = this.renderTarget2;
+ this.renderToScreen = true;
+ this.passes = []; // dependencies
+
+ if ( THREE.CopyShader === undefined ) {
+
+ console.error( 'THREE.EffectComposer relies on THREE.CopyShader' );
+
+ }
+
+ if ( THREE.ShaderPass === undefined ) {
+
+ console.error( 'THREE.EffectComposer relies on THREE.ShaderPass' );
+
+ }
+
+ this.copyPass = new THREE.ShaderPass( THREE.CopyShader );
+ this.clock = new THREE.Clock();
+
+ }
+
+ swapBuffers() {
+
+ const tmp = this.readBuffer;
+ this.readBuffer = this.writeBuffer;
+ this.writeBuffer = tmp;
+
+ }
+
+ addPass( pass ) {
+
+ this.passes.push( pass );
+ pass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
+
+ }
+
+ insertPass( pass, index ) {
+
+ this.passes.splice( index, 0, pass );
+ pass.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
+
+ }
+
+ removePass( pass ) {
+
+ const index = this.passes.indexOf( pass );
+
+ if ( index !== - 1 ) {
+
+ this.passes.splice( index, 1 );
+
+ }
+
+ }
+
+ isLastEnabledPass( passIndex ) {
+
+ for ( let i = passIndex + 1; i < this.passes.length; i ++ ) {
+
+ if ( this.passes[ i ].enabled ) {
+
+ return false;
+
+ }
+
+ }
+
+ return true;
+
+ }
+
+ render( deltaTime ) {
+
+ // deltaTime value is in seconds
+ if ( deltaTime === undefined ) {
+
+ deltaTime = this.clock.getDelta();
+
+ }
+
+ const currentRenderTarget = this.renderer.getRenderTarget();
+ let maskActive = false;
+
+ for ( let i = 0, il = this.passes.length; i < il; i ++ ) {
+
+ const pass = this.passes[ i ];
+ if ( pass.enabled === false ) continue;
+ pass.renderToScreen = this.renderToScreen && this.isLastEnabledPass( i );
+ pass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime, maskActive );
+
+ if ( pass.needsSwap ) {
+
+ if ( maskActive ) {
+
+ const context = this.renderer.getContext();
+ const stencil = this.renderer.state.buffers.stencil; //context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );
+
+ stencil.setFunc( context.NOTEQUAL, 1, 0xffffffff );
+ this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, deltaTime ); //context.stencilFunc( context.EQUAL, 1, 0xffffffff );
+
+ stencil.setFunc( context.EQUAL, 1, 0xffffffff );
+
+ }
+
+ this.swapBuffers();
+
+ }
+
+ if ( THREE.MaskPass !== undefined ) {
+
+ if ( pass instanceof THREE.MaskPass ) {
+
+ maskActive = true;
+
+ } else if ( pass instanceof THREE.ClearMaskPass ) {
+
+ maskActive = false;
+
+ }
+
+ }
+
+ }
+
+ this.renderer.setRenderTarget( currentRenderTarget );
+
+ }
+
+ reset( renderTarget ) {
+
+ if ( renderTarget === undefined ) {
+
+ const size = this.renderer.getSize( new THREE.Vector2() );
+ this._pixelRatio = this.renderer.getPixelRatio();
+ this._width = size.width;
+ this._height = size.height;
+ renderTarget = this.renderTarget1.clone();
+ renderTarget.setSize( this._width * this._pixelRatio, this._height * this._pixelRatio );
+
+ }
+
+ this.renderTarget1.dispose();
+ this.renderTarget2.dispose();
+ this.renderTarget1 = renderTarget;
+ this.renderTarget2 = renderTarget.clone();
+ this.writeBuffer = this.renderTarget1;
+ this.readBuffer = this.renderTarget2;
+
+ }
+
+ setSize( width, height ) {
+
+ this._width = width;
+ this._height = height;
+ const effectiveWidth = this._width * this._pixelRatio;
+ const effectiveHeight = this._height * this._pixelRatio;
+ this.renderTarget1.setSize( effectiveWidth, effectiveHeight );
+ this.renderTarget2.setSize( effectiveWidth, effectiveHeight );
+
+ for ( let i = 0; i < this.passes.length; i ++ ) {
+
+ this.passes[ i ].setSize( effectiveWidth, effectiveHeight );
+
+ }
+
+ }
+
+ setPixelRatio( pixelRatio ) {
+
+ this._pixelRatio = pixelRatio;
+ this.setSize( this._width, this._height );
+
+ }
+
+ }
+
+ class Pass {
+
+ constructor() {
+
+ // if set to true, the pass is processed by the composer
+ this.enabled = true; // if set to true, the pass indicates to swap read and write buffer after rendering
+
+ this.needsSwap = true; // if set to true, the pass clears its buffer before rendering
+
+ this.clear = false; // if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.
+
+ this.renderToScreen = false;
+
+ }
+
+ setSize( ) {}
+
+ render( ) {
+
+ console.error( 'THREE.Pass: .render() must be implemented in derived pass.' );
+
+ }
+
+ } // Helper for passes that need to fill the viewport with a single quad.
+
+
+ const _camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 ); // https://github.com/mrdoob/three.js/pull/21358
+
+
+ const _geometry = new THREE.BufferGeometry();
+
+ _geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );
+
+ _geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );
+
+ class FullScreenQuad {
+
+ constructor( material ) {
+
+ this._mesh = new THREE.Mesh( _geometry, material );
+
+ }
+
+ dispose() {
+
+ this._mesh.geometry.dispose();
+
+ }
+
+ render( renderer ) {
+
+ renderer.render( this._mesh, _camera );
+
+ }
+
+ get material() {
+
+ return this._mesh.material;
+
+ }
+
+ set material( value ) {
+
+ this._mesh.material = value;
+
+ }
+
+ }
+
+ THREE.EffectComposer = EffectComposer;
+ THREE.FullScreenQuad = FullScreenQuad;
+ THREE.Pass = Pass;
+
+} )();
diff --git a/downloads/GLTFLoader.js b/downloads/GLTFLoader.js
new file mode 100644
index 0000000..cfa518e
--- /dev/null
+++ b/downloads/GLTFLoader.js
@@ -0,0 +1,3629 @@
+( function () {
+
+ class GLTFLoader extends THREE.Loader {
+
+ constructor( manager ) {
+
+ super( manager );
+ this.dracoLoader = null;
+ this.ktx2Loader = null;
+ this.meshoptDecoder = null;
+ this.pluginCallbacks = [];
+ this.register( function ( parser ) {
+
+ return new GLTFMaterialsClearcoatExtension( parser );
+
+ } );
+ this.register( function ( parser ) {
+
+ return new GLTFTextureBasisUExtension( parser );
+
+ } );
+ this.register( function ( parser ) {
+
+ return new GLTFTextureWebPExtension( parser );
+
+ } );
+ this.register( function ( parser ) {
+
+ return new GLTFMaterialsTransmissionExtension( parser );
+
+ } );
+ this.register( function ( parser ) {
+
+ return new GLTFLightsExtension( parser );
+
+ } );
+ this.register( function ( parser ) {
+
+ return new GLTFMeshoptCompression( parser );
+
+ } );
+
+ }
+
+ load( url, onLoad, onProgress, onError ) {
+
+ const scope = this;
+ let resourcePath;
+
+ if ( this.resourcePath !== '' ) {
+
+ resourcePath = this.resourcePath;
+
+ } else if ( this.path !== '' ) {
+
+ resourcePath = this.path;
+
+ } else {
+
+ resourcePath = THREE.LoaderUtils.extractUrlBase( url );
+
+ } // Tells the LoadingManager to track an extra item, which resolves after
+ // the model is fully loaded. This means the count of items loaded will
+ // be incorrect, but ensures manager.onLoad() does not fire early.
+
+
+ this.manager.itemStart( url );
+
+ const _onError = function ( e ) {
+
+ if ( onError ) {
+
+ onError( e );
+
+ } else {
+
+ console.error( e );
+
+ }
+
+ scope.manager.itemError( url );
+ scope.manager.itemEnd( url );
+
+ };
+
+ const loader = new THREE.FileLoader( this.manager );
+ loader.setPath( this.path );
+ loader.setResponseType( 'arraybuffer' );
+ loader.setRequestHeader( this.requestHeader );
+ loader.setWithCredentials( this.withCredentials );
+ loader.load( url, function ( data ) {
+
+ try {
+
+ scope.parse( data, resourcePath, function ( gltf ) {
+
+ onLoad( gltf );
+ scope.manager.itemEnd( url );
+
+ }, _onError );
+
+ } catch ( e ) {
+
+ _onError( e );
+
+ }
+
+ }, onProgress, _onError );
+
+ }
+
+ setDRACOLoader( dracoLoader ) {
+
+ this.dracoLoader = dracoLoader;
+ return this;
+
+ }
+
+ setDDSLoader() {
+
+ throw new Error( 'THREE.GLTFLoader: "MSFT_texture_dds" no longer supported. Please update to "KHR_texture_basisu".' );
+
+ }
+
+ setKTX2Loader( ktx2Loader ) {
+
+ this.ktx2Loader = ktx2Loader;
+ return this;
+
+ }
+
+ setMeshoptDecoder( meshoptDecoder ) {
+
+ this.meshoptDecoder = meshoptDecoder;
+ return this;
+
+ }
+
+ register( callback ) {
+
+ if ( this.pluginCallbacks.indexOf( callback ) === - 1 ) {
+
+ this.pluginCallbacks.push( callback );
+
+ }
+
+ return this;
+
+ }
+
+ unregister( callback ) {
+
+ if ( this.pluginCallbacks.indexOf( callback ) !== - 1 ) {
+
+ this.pluginCallbacks.splice( this.pluginCallbacks.indexOf( callback ), 1 );
+
+ }
+
+ return this;
+
+ }
+
+ parse( data, path, onLoad, onError ) {
+
+ let content;
+ const extensions = {};
+ const plugins = {};
+
+ if ( typeof data === 'string' ) {
+
+ content = data;
+
+ } else {
+
+ const magic = THREE.LoaderUtils.decodeText( new Uint8Array( data, 0, 4 ) );
+
+ if ( magic === BINARY_EXTENSION_HEADER_MAGIC ) {
+
+ try {
+
+ extensions[ EXTENSIONS.KHR_BINARY_GLTF ] = new GLTFBinaryExtension( data );
+
+ } catch ( error ) {
+
+ if ( onError ) onError( error );
+ return;
+
+ }
+
+ content = extensions[ EXTENSIONS.KHR_BINARY_GLTF ].content;
+
+ } else {
+
+ content = THREE.LoaderUtils.decodeText( new Uint8Array( data ) );
+
+ }
+
+ }
+
+ const json = JSON.parse( content );
+
+ if ( json.asset === undefined || json.asset.version[ 0 ] < 2 ) {
+
+ if ( onError ) onError( new Error( 'THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.' ) );
+ return;
+
+ }
+
+ const parser = new GLTFParser( json, {
+ path: path || this.resourcePath || '',
+ crossOrigin: this.crossOrigin,
+ requestHeader: this.requestHeader,
+ manager: this.manager,
+ ktx2Loader: this.ktx2Loader,
+ meshoptDecoder: this.meshoptDecoder
+ } );
+ parser.fileLoader.setRequestHeader( this.requestHeader );
+
+ for ( let i = 0; i < this.pluginCallbacks.length; i ++ ) {
+
+ const plugin = this.pluginCallbacks[ i ]( parser );
+ plugins[ plugin.name ] = plugin; // Workaround to avoid determining as unknown extension
+ // in addUnknownExtensionsToUserData().
+ // Remove this workaround if we move all the existing
+ // extension handlers to plugin system
+
+ extensions[ plugin.name ] = true;
+
+ }
+
+ if ( json.extensionsUsed ) {
+
+ for ( let i = 0; i < json.extensionsUsed.length; ++ i ) {
+
+ const extensionName = json.extensionsUsed[ i ];
+ const extensionsRequired = json.extensionsRequired || [];
+
+ switch ( extensionName ) {
+
+ case EXTENSIONS.KHR_MATERIALS_UNLIT:
+ extensions[ extensionName ] = new GLTFMaterialsUnlitExtension();
+ break;
+
+ case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS:
+ extensions[ extensionName ] = new GLTFMaterialsPbrSpecularGlossinessExtension();
+ break;
+
+ case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:
+ extensions[ extensionName ] = new GLTFDracoMeshCompressionExtension( json, this.dracoLoader );
+ break;
+
+ case EXTENSIONS.KHR_TEXTURE_TRANSFORM:
+ extensions[ extensionName ] = new GLTFTextureTransformExtension();
+ break;
+
+ case EXTENSIONS.KHR_MESH_QUANTIZATION:
+ extensions[ extensionName ] = new GLTFMeshQuantizationExtension();
+ break;
+
+ default:
+ if ( extensionsRequired.indexOf( extensionName ) >= 0 && plugins[ extensionName ] === undefined ) {
+
+ console.warn( 'THREE.GLTFLoader: Unknown extension "' + extensionName + '".' );
+
+ }
+
+ }
+
+ }
+
+ }
+
+ parser.setExtensions( extensions );
+ parser.setPlugins( plugins );
+ parser.parse( onLoad, onError );
+
+ }
+
+ }
+ /* GLTFREGISTRY */
+
+
+ function GLTFRegistry() {
+
+ let objects = {};
+ return {
+ get: function ( key ) {
+
+ return objects[ key ];
+
+ },
+ add: function ( key, object ) {
+
+ objects[ key ] = object;
+
+ },
+ remove: function ( key ) {
+
+ delete objects[ key ];
+
+ },
+ removeAll: function () {
+
+ objects = {};
+
+ }
+ };
+
+ }
+ /*********************************/
+
+ /********** EXTENSIONS ***********/
+
+ /*********************************/
+
+
+ const EXTENSIONS = {
+ KHR_BINARY_GLTF: 'KHR_binary_glTF',
+ KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',
+ KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',
+ KHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',
+ KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',
+ KHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission',
+ KHR_MATERIALS_UNLIT: 'KHR_materials_unlit',
+ KHR_TEXTURE_BASISU: 'KHR_texture_basisu',
+ KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
+ KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',
+ EXT_TEXTURE_WEBP: 'EXT_texture_webp',
+ EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression'
+ };
+ /**
+ * Punctual Lights Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
+ */
+
+ class GLTFLightsExtension {
+
+ constructor( parser ) {
+
+ this.parser = parser;
+ this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL; // THREE.Object3D instance caches
+
+ this.cache = {
+ refs: {},
+ uses: {}
+ };
+
+ }
+
+ _markDefs() {
+
+ const parser = this.parser;
+ const nodeDefs = this.parser.json.nodes || [];
+
+ for ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {
+
+ const nodeDef = nodeDefs[ nodeIndex ];
+
+ if ( nodeDef.extensions && nodeDef.extensions[ this.name ] && nodeDef.extensions[ this.name ].light !== undefined ) {
+
+ parser._addNodeRef( this.cache, nodeDef.extensions[ this.name ].light );
+
+ }
+
+ }
+
+ }
+
+ _loadLight( lightIndex ) {
+
+ const parser = this.parser;
+ const cacheKey = 'light:' + lightIndex;
+ let dependency = parser.cache.get( cacheKey );
+ if ( dependency ) return dependency;
+ const json = parser.json;
+ const extensions = json.extensions && json.extensions[ this.name ] || {};
+ const lightDefs = extensions.lights || [];
+ const lightDef = lightDefs[ lightIndex ];
+ let lightNode;
+ const color = new THREE.Color( 0xffffff );
+ if ( lightDef.color !== undefined ) color.fromArray( lightDef.color );
+ const range = lightDef.range !== undefined ? lightDef.range : 0;
+
+ switch ( lightDef.type ) {
+
+ case 'directional':
+ lightNode = new THREE.DirectionalLight( color );
+ lightNode.target.position.set( 0, 0, - 1 );
+ lightNode.add( lightNode.target );
+ break;
+
+ case 'point':
+ lightNode = new THREE.PointLight( color );
+ lightNode.distance = range;
+ break;
+
+ case 'spot':
+ lightNode = new THREE.SpotLight( color );
+ lightNode.distance = range; // Handle spotlight properties.
+
+ lightDef.spot = lightDef.spot || {};
+ lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0;
+ lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0;
+ lightNode.angle = lightDef.spot.outerConeAngle;
+ lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle;
+ lightNode.target.position.set( 0, 0, - 1 );
+ lightNode.add( lightNode.target );
+ break;
+
+ default:
+ throw new Error( 'THREE.GLTFLoader: Unexpected light type: ' + lightDef.type );
+
+ } // Some lights (e.g. spot) default to a position other than the origin. Reset the position
+ // here, because node-level parsing will only override position if explicitly specified.
+
+
+ lightNode.position.set( 0, 0, 0 );
+ lightNode.decay = 2;
+ if ( lightDef.intensity !== undefined ) lightNode.intensity = lightDef.intensity;
+ lightNode.name = parser.createUniqueName( lightDef.name || 'light_' + lightIndex );
+ dependency = Promise.resolve( lightNode );
+ parser.cache.add( cacheKey, dependency );
+ return dependency;
+
+ }
+
+ createNodeAttachment( nodeIndex ) {
+
+ const self = this;
+ const parser = this.parser;
+ const json = parser.json;
+ const nodeDef = json.nodes[ nodeIndex ];
+ const lightDef = nodeDef.extensions && nodeDef.extensions[ this.name ] || {};
+ const lightIndex = lightDef.light;
+ if ( lightIndex === undefined ) return null;
+ return this._loadLight( lightIndex ).then( function ( light ) {
+
+ return parser._getNodeRef( self.cache, lightIndex, light );
+
+ } );
+
+ }
+
+ }
+ /**
+ * Unlit Materials Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit
+ */
+
+
+ class GLTFMaterialsUnlitExtension {
+
+ constructor() {
+
+ this.name = EXTENSIONS.KHR_MATERIALS_UNLIT;
+
+ }
+
+ getMaterialType() {
+
+ return THREE.MeshBasicMaterial;
+
+ }
+
+ extendParams( materialParams, materialDef, parser ) {
+
+ const pending = [];
+ materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
+ materialParams.opacity = 1.0;
+ const metallicRoughness = materialDef.pbrMetallicRoughness;
+
+ if ( metallicRoughness ) {
+
+ if ( Array.isArray( metallicRoughness.baseColorFactor ) ) {
+
+ const array = metallicRoughness.baseColorFactor;
+ materialParams.color.fromArray( array );
+ materialParams.opacity = array[ 3 ];
+
+ }
+
+ if ( metallicRoughness.baseColorTexture !== undefined ) {
+
+ pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture ) );
+
+ }
+
+ }
+
+ return Promise.all( pending );
+
+ }
+
+ }
+ /**
+ * Clearcoat Materials Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
+ */
+
+
+ class GLTFMaterialsClearcoatExtension {
+
+ constructor( parser ) {
+
+ this.parser = parser;
+ this.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT;
+
+ }
+
+ getMaterialType( materialIndex ) {
+
+ const parser = this.parser;
+ const materialDef = parser.json.materials[ materialIndex ];
+ if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
+ return THREE.MeshPhysicalMaterial;
+
+ }
+
+ extendMaterialParams( materialIndex, materialParams ) {
+
+ const parser = this.parser;
+ const materialDef = parser.json.materials[ materialIndex ];
+
+ if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
+
+ return Promise.resolve();
+
+ }
+
+ const pending = [];
+ const extension = materialDef.extensions[ this.name ];
+
+ if ( extension.clearcoatFactor !== undefined ) {
+
+ materialParams.clearcoat = extension.clearcoatFactor;
+
+ }
+
+ if ( extension.clearcoatTexture !== undefined ) {
+
+ pending.push( parser.assignTexture( materialParams, 'clearcoatMap', extension.clearcoatTexture ) );
+
+ }
+
+ if ( extension.clearcoatRoughnessFactor !== undefined ) {
+
+ materialParams.clearcoatRoughness = extension.clearcoatRoughnessFactor;
+
+ }
+
+ if ( extension.clearcoatRoughnessTexture !== undefined ) {
+
+ pending.push( parser.assignTexture( materialParams, 'clearcoatRoughnessMap', extension.clearcoatRoughnessTexture ) );
+
+ }
+
+ if ( extension.clearcoatNormalTexture !== undefined ) {
+
+ pending.push( parser.assignTexture( materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture ) );
+
+ if ( extension.clearcoatNormalTexture.scale !== undefined ) {
+
+ const scale = extension.clearcoatNormalTexture.scale; // https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
+
+ materialParams.clearcoatNormalScale = new THREE.Vector2( scale, - scale );
+
+ }
+
+ }
+
+ return Promise.all( pending );
+
+ }
+
+ }
+ /**
+ * Transmission Materials Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
+ * Draft: https://github.com/KhronosGroup/glTF/pull/1698
+ */
+
+
+ class GLTFMaterialsTransmissionExtension {
+
+ constructor( parser ) {
+
+ this.parser = parser;
+ this.name = EXTENSIONS.KHR_MATERIALS_TRANSMISSION;
+
+ }
+
+ getMaterialType( materialIndex ) {
+
+ const parser = this.parser;
+ const materialDef = parser.json.materials[ materialIndex ];
+ if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) return null;
+ return THREE.MeshPhysicalMaterial;
+
+ }
+
+ extendMaterialParams( materialIndex, materialParams ) {
+
+ const parser = this.parser;
+ const materialDef = parser.json.materials[ materialIndex ];
+
+ if ( ! materialDef.extensions || ! materialDef.extensions[ this.name ] ) {
+
+ return Promise.resolve();
+
+ }
+
+ const pending = [];
+ const extension = materialDef.extensions[ this.name ];
+
+ if ( extension.transmissionFactor !== undefined ) {
+
+ materialParams.transmission = extension.transmissionFactor;
+
+ }
+
+ if ( extension.transmissionTexture !== undefined ) {
+
+ pending.push( parser.assignTexture( materialParams, 'transmissionMap', extension.transmissionTexture ) );
+
+ }
+
+ return Promise.all( pending );
+
+ }
+
+ }
+ /**
+ * BasisU Texture Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu
+ */
+
+
+ class GLTFTextureBasisUExtension {
+
+ constructor( parser ) {
+
+ this.parser = parser;
+ this.name = EXTENSIONS.KHR_TEXTURE_BASISU;
+
+ }
+
+ loadTexture( textureIndex ) {
+
+ const parser = this.parser;
+ const json = parser.json;
+ const textureDef = json.textures[ textureIndex ];
+
+ if ( ! textureDef.extensions || ! textureDef.extensions[ this.name ] ) {
+
+ return null;
+
+ }
+
+ const extension = textureDef.extensions[ this.name ];
+ const source = json.images[ extension.source ];
+ const loader = parser.options.ktx2Loader;
+
+ if ( ! loader ) {
+
+ if ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {
+
+ throw new Error( 'THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures' );
+
+ } else {
+
+ // Assumes that the extension is optional and that a fallback texture is present
+ return null;
+
+ }
+
+ }
+
+ return parser.loadTextureImage( textureIndex, source, loader );
+
+ }
+
+ }
+ /**
+ * WebP Texture Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_webp
+ */
+
+
+ class GLTFTextureWebPExtension {
+
+ constructor( parser ) {
+
+ this.parser = parser;
+ this.name = EXTENSIONS.EXT_TEXTURE_WEBP;
+ this.isSupported = null;
+
+ }
+
+ loadTexture( textureIndex ) {
+
+ const name = this.name;
+ const parser = this.parser;
+ const json = parser.json;
+ const textureDef = json.textures[ textureIndex ];
+
+ if ( ! textureDef.extensions || ! textureDef.extensions[ name ] ) {
+
+ return null;
+
+ }
+
+ const extension = textureDef.extensions[ name ];
+ const source = json.images[ extension.source ];
+ let loader = parser.textureLoader;
+
+ if ( source.uri ) {
+
+ const handler = parser.options.manager.getHandler( source.uri );
+ if ( handler !== null ) loader = handler;
+
+ }
+
+ return this.detectSupport().then( function ( isSupported ) {
+
+ if ( isSupported ) return parser.loadTextureImage( textureIndex, source, loader );
+
+ if ( json.extensionsRequired && json.extensionsRequired.indexOf( name ) >= 0 ) {
+
+ throw new Error( 'THREE.GLTFLoader: WebP required by asset but unsupported.' );
+
+ } // Fall back to PNG or JPEG.
+
+
+ return parser.loadTexture( textureIndex );
+
+ } );
+
+ }
+
+ detectSupport() {
+
+ if ( ! this.isSupported ) {
+
+ this.isSupported = new Promise( function ( resolve ) {
+
+ const image = new Image(); // Lossy test image. Support for lossy images doesn't guarantee support for all
+ // WebP images, unfortunately.
+
+ image.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA';
+
+ image.onload = image.onerror = function () {
+
+ resolve( image.height === 1 );
+
+ };
+
+ } );
+
+ }
+
+ return this.isSupported;
+
+ }
+
+ }
+ /**
+ * meshopt BufferView Compression Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression
+ */
+
+
+ class GLTFMeshoptCompression {
+
+ constructor( parser ) {
+
+ this.name = EXTENSIONS.EXT_MESHOPT_COMPRESSION;
+ this.parser = parser;
+
+ }
+
+ loadBufferView( index ) {
+
+ const json = this.parser.json;
+ const bufferView = json.bufferViews[ index ];
+
+ if ( bufferView.extensions && bufferView.extensions[ this.name ] ) {
+
+ const extensionDef = bufferView.extensions[ this.name ];
+ const buffer = this.parser.getDependency( 'buffer', extensionDef.buffer );
+ const decoder = this.parser.options.meshoptDecoder;
+
+ if ( ! decoder || ! decoder.supported ) {
+
+ if ( json.extensionsRequired && json.extensionsRequired.indexOf( this.name ) >= 0 ) {
+
+ throw new Error( 'THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files' );
+
+ } else {
+
+ // Assumes that the extension is optional and that fallback buffer data is present
+ return null;
+
+ }
+
+ }
+
+ return Promise.all( [ buffer, decoder.ready ] ).then( function ( res ) {
+
+ const byteOffset = extensionDef.byteOffset || 0;
+ const byteLength = extensionDef.byteLength || 0;
+ const count = extensionDef.count;
+ const stride = extensionDef.byteStride;
+ const result = new ArrayBuffer( count * stride );
+ const source = new Uint8Array( res[ 0 ], byteOffset, byteLength );
+ decoder.decodeGltfBuffer( new Uint8Array( result ), count, stride, source, extensionDef.mode, extensionDef.filter );
+ return result;
+
+ } );
+
+ } else {
+
+ return null;
+
+ }
+
+ }
+
+ }
+ /* BINARY EXTENSION */
+
+
+ const BINARY_EXTENSION_HEADER_MAGIC = 'glTF';
+ const BINARY_EXTENSION_HEADER_LENGTH = 12;
+ const BINARY_EXTENSION_CHUNK_TYPES = {
+ JSON: 0x4E4F534A,
+ BIN: 0x004E4942
+ };
+
+ class GLTFBinaryExtension {
+
+ constructor( data ) {
+
+ this.name = EXTENSIONS.KHR_BINARY_GLTF;
+ this.content = null;
+ this.body = null;
+ const headerView = new DataView( data, 0, BINARY_EXTENSION_HEADER_LENGTH );
+ this.header = {
+ magic: THREE.LoaderUtils.decodeText( new Uint8Array( data.slice( 0, 4 ) ) ),
+ version: headerView.getUint32( 4, true ),
+ length: headerView.getUint32( 8, true )
+ };
+
+ if ( this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC ) {
+
+ throw new Error( 'THREE.GLTFLoader: Unsupported glTF-Binary header.' );
+
+ } else if ( this.header.version < 2.0 ) {
+
+ throw new Error( 'THREE.GLTFLoader: Legacy binary file detected.' );
+
+ }
+
+ const chunkContentsLength = this.header.length - BINARY_EXTENSION_HEADER_LENGTH;
+ const chunkView = new DataView( data, BINARY_EXTENSION_HEADER_LENGTH );
+ let chunkIndex = 0;
+
+ while ( chunkIndex < chunkContentsLength ) {
+
+ const chunkLength = chunkView.getUint32( chunkIndex, true );
+ chunkIndex += 4;
+ const chunkType = chunkView.getUint32( chunkIndex, true );
+ chunkIndex += 4;
+
+ if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON ) {
+
+ const contentArray = new Uint8Array( data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength );
+ this.content = THREE.LoaderUtils.decodeText( contentArray );
+
+ } else if ( chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN ) {
+
+ const byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex;
+ this.body = data.slice( byteOffset, byteOffset + chunkLength );
+
+ } // Clients must ignore chunks with unknown types.
+
+
+ chunkIndex += chunkLength;
+
+ }
+
+ if ( this.content === null ) {
+
+ throw new Error( 'THREE.GLTFLoader: JSON content not found.' );
+
+ }
+
+ }
+
+ }
+ /**
+ * DRACO THREE.Mesh Compression Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression
+ */
+
+
+ class GLTFDracoMeshCompressionExtension {
+
+ constructor( json, dracoLoader ) {
+
+ if ( ! dracoLoader ) {
+
+ throw new Error( 'THREE.GLTFLoader: No DRACOLoader instance provided.' );
+
+ }
+
+ this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION;
+ this.json = json;
+ this.dracoLoader = dracoLoader;
+ this.dracoLoader.preload();
+
+ }
+
+ decodePrimitive( primitive, parser ) {
+
+ const json = this.json;
+ const dracoLoader = this.dracoLoader;
+ const bufferViewIndex = primitive.extensions[ this.name ].bufferView;
+ const gltfAttributeMap = primitive.extensions[ this.name ].attributes;
+ const threeAttributeMap = {};
+ const attributeNormalizedMap = {};
+ const attributeTypeMap = {};
+
+ for ( const attributeName in gltfAttributeMap ) {
+
+ const threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();
+ threeAttributeMap[ threeAttributeName ] = gltfAttributeMap[ attributeName ];
+
+ }
+
+ for ( const attributeName in primitive.attributes ) {
+
+ const threeAttributeName = ATTRIBUTES[ attributeName ] || attributeName.toLowerCase();
+
+ if ( gltfAttributeMap[ attributeName ] !== undefined ) {
+
+ const accessorDef = json.accessors[ primitive.attributes[ attributeName ] ];
+ const componentType = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ];
+ attributeTypeMap[ threeAttributeName ] = componentType;
+ attributeNormalizedMap[ threeAttributeName ] = accessorDef.normalized === true;
+
+ }
+
+ }
+
+ return parser.getDependency( 'bufferView', bufferViewIndex ).then( function ( bufferView ) {
+
+ return new Promise( function ( resolve ) {
+
+ dracoLoader.decodeDracoFile( bufferView, function ( geometry ) {
+
+ for ( const attributeName in geometry.attributes ) {
+
+ const attribute = geometry.attributes[ attributeName ];
+ const normalized = attributeNormalizedMap[ attributeName ];
+ if ( normalized !== undefined ) attribute.normalized = normalized;
+
+ }
+
+ resolve( geometry );
+
+ }, threeAttributeMap, attributeTypeMap );
+
+ } );
+
+ } );
+
+ }
+
+ }
+ /**
+ * Texture Transform Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform
+ */
+
+
+ class GLTFTextureTransformExtension {
+
+ constructor() {
+
+ this.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM;
+
+ }
+
+ extendTexture( texture, transform ) {
+
+ texture = texture.clone();
+
+ if ( transform.offset !== undefined ) {
+
+ texture.offset.fromArray( transform.offset );
+
+ }
+
+ if ( transform.rotation !== undefined ) {
+
+ texture.rotation = transform.rotation;
+
+ }
+
+ if ( transform.scale !== undefined ) {
+
+ texture.repeat.fromArray( transform.scale );
+
+ }
+
+ if ( transform.texCoord !== undefined ) {
+
+ console.warn( 'THREE.GLTFLoader: Custom UV sets in "' + this.name + '" extension not yet supported.' );
+
+ }
+
+ texture.needsUpdate = true;
+ return texture;
+
+ }
+
+ }
+ /**
+ * Specular-Glossiness Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness
+ */
+
+ /**
+ * A sub class of StandardMaterial with some of the functionality
+ * changed via the `onBeforeCompile` callback
+ * @pailhead
+ */
+
+
+ class GLTFMeshStandardSGMaterial extends THREE.MeshStandardMaterial {
+
+ constructor( params ) {
+
+ super();
+ this.isGLTFSpecularGlossinessMaterial = true; //various chunks that need replacing
+
+ const specularMapParsFragmentChunk = [ '#ifdef USE_SPECULARMAP', ' uniform sampler2D specularMap;', '#endif' ].join( '\n' );
+ const glossinessMapParsFragmentChunk = [ '#ifdef USE_GLOSSINESSMAP', ' uniform sampler2D glossinessMap;', '#endif' ].join( '\n' );
+ const specularMapFragmentChunk = [ 'vec3 specularFactor = specular;', '#ifdef USE_SPECULARMAP', ' vec4 texelSpecular = texture2D( specularMap, vUv );', ' texelSpecular = sRGBToLinear( texelSpecular );', ' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture', ' specularFactor *= texelSpecular.rgb;', '#endif' ].join( '\n' );
+ const glossinessMapFragmentChunk = [ 'float glossinessFactor = glossiness;', '#ifdef USE_GLOSSINESSMAP', ' vec4 texelGlossiness = texture2D( glossinessMap, vUv );', ' // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture', ' glossinessFactor *= texelGlossiness.a;', '#endif' ].join( '\n' );
+ const lightPhysicalFragmentChunk = [ 'PhysicalMaterial material;', 'material.diffuseColor = diffuseColor.rgb * ( 1. - max( specularFactor.r, max( specularFactor.g, specularFactor.b ) ) );', 'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );', 'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );', 'material.specularRoughness = max( 1.0 - glossinessFactor, 0.0525 ); // 0.0525 corresponds to the base mip of a 256 cubemap.', 'material.specularRoughness += geometryRoughness;', 'material.specularRoughness = min( material.specularRoughness, 1.0 );', 'material.specularColor = specularFactor;' ].join( '\n' );
+ const uniforms = {
+ specular: {
+ value: new THREE.Color().setHex( 0xffffff )
+ },
+ glossiness: {
+ value: 1
+ },
+ specularMap: {
+ value: null
+ },
+ glossinessMap: {
+ value: null
+ }
+ };
+ this._extraUniforms = uniforms;
+
+ this.onBeforeCompile = function ( shader ) {
+
+ for ( const uniformName in uniforms ) {
+
+ shader.uniforms[ uniformName ] = uniforms[ uniformName ];
+
+ }
+
+ shader.fragmentShader = shader.fragmentShader.replace( 'uniform float roughness;', 'uniform vec3 specular;' ).replace( 'uniform float metalness;', 'uniform float glossiness;' ).replace( '#include <roughnessmap_pars_fragment>', specularMapParsFragmentChunk ).replace( '#include <metalnessmap_pars_fragment>', glossinessMapParsFragmentChunk ).replace( '#include <roughnessmap_fragment>', specularMapFragmentChunk ).replace( '#include <metalnessmap_fragment>', glossinessMapFragmentChunk ).replace( '#include <lights_physical_fragment>', lightPhysicalFragmentChunk );
+
+ };
+
+ Object.defineProperties( this, {
+ specular: {
+ get: function () {
+
+ return uniforms.specular.value;
+
+ },
+ set: function ( v ) {
+
+ uniforms.specular.value = v;
+
+ }
+ },
+ specularMap: {
+ get: function () {
+
+ return uniforms.specularMap.value;
+
+ },
+ set: function ( v ) {
+
+ uniforms.specularMap.value = v;
+
+ if ( v ) {
+
+ this.defines.USE_SPECULARMAP = ''; // USE_UV is set by the renderer for specular maps
+
+ } else {
+
+ delete this.defines.USE_SPECULARMAP;
+
+ }
+
+ }
+ },
+ glossiness: {
+ get: function () {
+
+ return uniforms.glossiness.value;
+
+ },
+ set: function ( v ) {
+
+ uniforms.glossiness.value = v;
+
+ }
+ },
+ glossinessMap: {
+ get: function () {
+
+ return uniforms.glossinessMap.value;
+
+ },
+ set: function ( v ) {
+
+ uniforms.glossinessMap.value = v;
+
+ if ( v ) {
+
+ this.defines.USE_GLOSSINESSMAP = '';
+ this.defines.USE_UV = '';
+
+ } else {
+
+ delete this.defines.USE_GLOSSINESSMAP;
+ delete this.defines.USE_UV;
+
+ }
+
+ }
+ }
+ } );
+ delete this.metalness;
+ delete this.roughness;
+ delete this.metalnessMap;
+ delete this.roughnessMap;
+ this.setValues( params );
+
+ }
+
+ copy( source ) {
+
+ super.copy( source );
+ this.specularMap = source.specularMap;
+ this.specular.copy( source.specular );
+ this.glossinessMap = source.glossinessMap;
+ this.glossiness = source.glossiness;
+ delete this.metalness;
+ delete this.roughness;
+ delete this.metalnessMap;
+ delete this.roughnessMap;
+ return this;
+
+ }
+
+ }
+
+ class GLTFMaterialsPbrSpecularGlossinessExtension {
+
+ constructor() {
+
+ this.name = EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS;
+ this.specularGlossinessParams = [ 'color', 'map', 'lightMap', 'lightMapIntensity', 'aoMap', 'aoMapIntensity', 'emissive', 'emissiveIntensity', 'emissiveMap', 'bumpMap', 'bumpScale', 'normalMap', 'normalMapType', 'displacementMap', 'displacementScale', 'displacementBias', 'specularMap', 'specular', 'glossinessMap', 'glossiness', 'alphaMap', 'envMap', 'envMapIntensity', 'refractionRatio' ];
+
+ }
+
+ getMaterialType() {
+
+ return GLTFMeshStandardSGMaterial;
+
+ }
+
+ extendParams( materialParams, materialDef, parser ) {
+
+ const pbrSpecularGlossiness = materialDef.extensions[ this.name ];
+ materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
+ materialParams.opacity = 1.0;
+ const pending = [];
+
+ if ( Array.isArray( pbrSpecularGlossiness.diffuseFactor ) ) {
+
+ const array = pbrSpecularGlossiness.diffuseFactor;
+ materialParams.color.fromArray( array );
+ materialParams.opacity = array[ 3 ];
+
+ }
+
+ if ( pbrSpecularGlossiness.diffuseTexture !== undefined ) {
+
+ pending.push( parser.assignTexture( materialParams, 'map', pbrSpecularGlossiness.diffuseTexture ) );
+
+ }
+
+ materialParams.emissive = new THREE.Color( 0.0, 0.0, 0.0 );
+ materialParams.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0;
+ materialParams.specular = new THREE.Color( 1.0, 1.0, 1.0 );
+
+ if ( Array.isArray( pbrSpecularGlossiness.specularFactor ) ) {
+
+ materialParams.specular.fromArray( pbrSpecularGlossiness.specularFactor );
+
+ }
+
+ if ( pbrSpecularGlossiness.specularGlossinessTexture !== undefined ) {
+
+ const specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture;
+ pending.push( parser.assignTexture( materialParams, 'glossinessMap', specGlossMapDef ) );
+ pending.push( parser.assignTexture( materialParams, 'specularMap', specGlossMapDef ) );
+
+ }
+
+ return Promise.all( pending );
+
+ }
+
+ createMaterial( materialParams ) {
+
+ const material = new GLTFMeshStandardSGMaterial( materialParams );
+ material.fog = true;
+ material.color = materialParams.color;
+ material.map = materialParams.map === undefined ? null : materialParams.map;
+ material.lightMap = null;
+ material.lightMapIntensity = 1.0;
+ material.aoMap = materialParams.aoMap === undefined ? null : materialParams.aoMap;
+ material.aoMapIntensity = 1.0;
+ material.emissive = materialParams.emissive;
+ material.emissiveIntensity = 1.0;
+ material.emissiveMap = materialParams.emissiveMap === undefined ? null : materialParams.emissiveMap;
+ material.bumpMap = materialParams.bumpMap === undefined ? null : materialParams.bumpMap;
+ material.bumpScale = 1;
+ material.normalMap = materialParams.normalMap === undefined ? null : materialParams.normalMap;
+ material.normalMapType = THREE.TangentSpaceNormalMap;
+ if ( materialParams.normalScale ) material.normalScale = materialParams.normalScale;
+ material.displacementMap = null;
+ material.displacementScale = 1;
+ material.displacementBias = 0;
+ material.specularMap = materialParams.specularMap === undefined ? null : materialParams.specularMap;
+ material.specular = materialParams.specular;
+ material.glossinessMap = materialParams.glossinessMap === undefined ? null : materialParams.glossinessMap;
+ material.glossiness = materialParams.glossiness;
+ material.alphaMap = null;
+ material.envMap = materialParams.envMap === undefined ? null : materialParams.envMap;
+ material.envMapIntensity = 1.0;
+ material.refractionRatio = 0.98;
+ return material;
+
+ }
+
+ }
+ /**
+ * THREE.Mesh Quantization Extension
+ *
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization
+ */
+
+
+ class GLTFMeshQuantizationExtension {
+
+ constructor() {
+
+ this.name = EXTENSIONS.KHR_MESH_QUANTIZATION;
+
+ }
+
+ }
+ /*********************************/
+
+ /********** INTERPOLATION ********/
+
+ /*********************************/
+ // Spline Interpolation
+ // Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation
+
+
+ class GLTFCubicSplineInterpolant extends THREE.Interpolant {
+
+ constructor( parameterPositions, sampleValues, sampleSize, resultBuffer ) {
+
+ super( parameterPositions, sampleValues, sampleSize, resultBuffer );
+
+ }
+
+ copySampleValue_( index ) {
+
+ // Copies a sample value to the result buffer. See description of glTF
+ // CUBICSPLINE values layout in interpolate_() function below.
+ const result = this.resultBuffer,
+ values = this.sampleValues,
+ valueSize = this.valueSize,
+ offset = index * valueSize * 3 + valueSize;
+
+ for ( let i = 0; i !== valueSize; i ++ ) {
+
+ result[ i ] = values[ offset + i ];
+
+ }
+
+ return result;
+
+ }
+
+ }
+
+ GLTFCubicSplineInterpolant.prototype.beforeStart_ = GLTFCubicSplineInterpolant.prototype.copySampleValue_;
+ GLTFCubicSplineInterpolant.prototype.afterEnd_ = GLTFCubicSplineInterpolant.prototype.copySampleValue_;
+
+ GLTFCubicSplineInterpolant.prototype.interpolate_ = function ( i1, t0, t, t1 ) {
+
+ const result = this.resultBuffer;
+ const values = this.sampleValues;
+ const stride = this.valueSize;
+ const stride2 = stride * 2;
+ const stride3 = stride * 3;
+ const td = t1 - t0;
+ const p = ( t - t0 ) / td;
+ const pp = p * p;
+ const ppp = pp * p;
+ const offset1 = i1 * stride3;
+ const offset0 = offset1 - stride3;
+ const s2 = - 2 * ppp + 3 * pp;
+ const s3 = ppp - pp;
+ const s0 = 1 - s2;
+ const s1 = s3 - pp + p; // Layout of keyframe output values for CUBICSPLINE animations:
+ // [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
+
+ for ( let i = 0; i !== stride; i ++ ) {
+
+ const p0 = values[ offset0 + i + stride ]; // splineVertex_k
+
+ const m0 = values[ offset0 + i + stride2 ] * td; // outTangent_k * (t_k+1 - t_k)
+
+ const p1 = values[ offset1 + i + stride ]; // splineVertex_k+1
+
+ const m1 = values[ offset1 + i ] * td; // inTangent_k+1 * (t_k+1 - t_k)
+
+ result[ i ] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1;
+
+ }
+
+ return result;
+
+ };
+ /*********************************/
+
+ /********** INTERNALS ************/
+
+ /*********************************/
+
+ /* CONSTANTS */
+
+
+ const WEBGL_CONSTANTS = {
+ FLOAT: 5126,
+ //FLOAT_MAT2: 35674,
+ FLOAT_MAT3: 35675,
+ FLOAT_MAT4: 35676,
+ FLOAT_VEC2: 35664,
+ FLOAT_VEC3: 35665,
+ FLOAT_VEC4: 35666,
+ LINEAR: 9729,
+ REPEAT: 10497,
+ SAMPLER_2D: 35678,
+ POINTS: 0,
+ LINES: 1,
+ LINE_LOOP: 2,
+ LINE_STRIP: 3,
+ TRIANGLES: 4,
+ TRIANGLE_STRIP: 5,
+ TRIANGLE_FAN: 6,
+ UNSIGNED_BYTE: 5121,
+ UNSIGNED_SHORT: 5123
+ };
+ const WEBGL_COMPONENT_TYPES = {
+ 5120: Int8Array,
+ 5121: Uint8Array,
+ 5122: Int16Array,
+ 5123: Uint16Array,
+ 5125: Uint32Array,
+ 5126: Float32Array
+ };
+ const WEBGL_FILTERS = {
+ 9728: THREE.NearestFilter,
+ 9729: THREE.LinearFilter,
+ 9984: THREE.NearestMipmapNearestFilter,
+ 9985: THREE.LinearMipmapNearestFilter,
+ 9986: THREE.NearestMipmapLinearFilter,
+ 9987: THREE.LinearMipmapLinearFilter
+ };
+ const WEBGL_WRAPPINGS = {
+ 33071: THREE.ClampToEdgeWrapping,
+ 33648: THREE.MirroredRepeatWrapping,
+ 10497: THREE.RepeatWrapping
+ };
+ const WEBGL_TYPE_SIZES = {
+ 'SCALAR': 1,
+ 'VEC2': 2,
+ 'VEC3': 3,
+ 'VEC4': 4,
+ 'MAT2': 4,
+ 'MAT3': 9,
+ 'MAT4': 16
+ };
+ const ATTRIBUTES = {
+ POSITION: 'position',
+ NORMAL: 'normal',
+ TANGENT: 'tangent',
+ TEXCOORD_0: 'uv',
+ TEXCOORD_1: 'uv2',
+ COLOR_0: 'color',
+ WEIGHTS_0: 'skinWeight',
+ JOINTS_0: 'skinIndex'
+ };
+ const PATH_PROPERTIES = {
+ scale: 'scale',
+ translation: 'position',
+ rotation: 'quaternion',
+ weights: 'morphTargetInfluences'
+ };
+ const INTERPOLATION = {
+ CUBICSPLINE: undefined,
+ // We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each
+ // keyframe track will be initialized with a default interpolation type, then modified.
+ LINEAR: THREE.InterpolateLinear,
+ STEP: THREE.InterpolateDiscrete
+ };
+ const ALPHA_MODES = {
+ OPAQUE: 'OPAQUE',
+ MASK: 'MASK',
+ BLEND: 'BLEND'
+ };
+ /* UTILITY FUNCTIONS */
+
+ function resolveURL( url, path ) {
+
+ // Invalid URL
+ if ( typeof url !== 'string' || url === '' ) return ''; // Host Relative URL
+
+ if ( /^https?:\/\//i.test( path ) && /^\//.test( url ) ) {
+
+ path = path.replace( /(^https?:\/\/[^\/]+).*/i, '$1' );
+
+ } // Absolute URL http://,https://,//
+
+
+ if ( /^(https?:)?\/\//i.test( url ) ) return url; // Data URI
+
+ if ( /^data:.*,.*$/i.test( url ) ) return url; // Blob URL
+
+ if ( /^blob:.*$/i.test( url ) ) return url; // Relative URL
+
+ return path + url;
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material
+ */
+
+
+ function createDefaultMaterial( cache ) {
+
+ if ( cache[ 'DefaultMaterial' ] === undefined ) {
+
+ cache[ 'DefaultMaterial' ] = new THREE.MeshStandardMaterial( {
+ color: 0xFFFFFF,
+ emissive: 0x000000,
+ metalness: 1,
+ roughness: 1,
+ transparent: false,
+ depthTest: true,
+ side: THREE.FrontSide
+ } );
+
+ }
+
+ return cache[ 'DefaultMaterial' ];
+
+ }
+
+ function addUnknownExtensionsToUserData( knownExtensions, object, objectDef ) {
+
+ // Add unknown glTF extensions to an object's userData.
+ for ( const name in objectDef.extensions ) {
+
+ if ( knownExtensions[ name ] === undefined ) {
+
+ object.userData.gltfExtensions = object.userData.gltfExtensions || {};
+ object.userData.gltfExtensions[ name ] = objectDef.extensions[ name ];
+
+ }
+
+ }
+
+ }
+ /**
+ * @param {Object3D|Material|BufferGeometry} object
+ * @param {GLTF.definition} gltfDef
+ */
+
+
+ function assignExtrasToUserData( object, gltfDef ) {
+
+ if ( gltfDef.extras !== undefined ) {
+
+ if ( typeof gltfDef.extras === 'object' ) {
+
+ Object.assign( object.userData, gltfDef.extras );
+
+ } else {
+
+ console.warn( 'THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras );
+
+ }
+
+ }
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets
+ *
+ * @param {BufferGeometry} geometry
+ * @param {Array<GLTF.Target>} targets
+ * @param {GLTFParser} parser
+ * @return {Promise<BufferGeometry>}
+ */
+
+
+ function addMorphTargets( geometry, targets, parser ) {
+
+ let hasMorphPosition = false;
+ let hasMorphNormal = false;
+
+ for ( let i = 0, il = targets.length; i < il; i ++ ) {
+
+ const target = targets[ i ];
+ if ( target.POSITION !== undefined ) hasMorphPosition = true;
+ if ( target.NORMAL !== undefined ) hasMorphNormal = true;
+ if ( hasMorphPosition && hasMorphNormal ) break;
+
+ }
+
+ if ( ! hasMorphPosition && ! hasMorphNormal ) return Promise.resolve( geometry );
+ const pendingPositionAccessors = [];
+ const pendingNormalAccessors = [];
+
+ for ( let i = 0, il = targets.length; i < il; i ++ ) {
+
+ const target = targets[ i ];
+
+ if ( hasMorphPosition ) {
+
+ const pendingAccessor = target.POSITION !== undefined ? parser.getDependency( 'accessor', target.POSITION ) : geometry.attributes.position;
+ pendingPositionAccessors.push( pendingAccessor );
+
+ }
+
+ if ( hasMorphNormal ) {
+
+ const pendingAccessor = target.NORMAL !== undefined ? parser.getDependency( 'accessor', target.NORMAL ) : geometry.attributes.normal;
+ pendingNormalAccessors.push( pendingAccessor );
+
+ }
+
+ }
+
+ return Promise.all( [ Promise.all( pendingPositionAccessors ), Promise.all( pendingNormalAccessors ) ] ).then( function ( accessors ) {
+
+ const morphPositions = accessors[ 0 ];
+ const morphNormals = accessors[ 1 ];
+ if ( hasMorphPosition ) geometry.morphAttributes.position = morphPositions;
+ if ( hasMorphNormal ) geometry.morphAttributes.normal = morphNormals;
+ geometry.morphTargetsRelative = true;
+ return geometry;
+
+ } );
+
+ }
+ /**
+ * @param {Mesh} mesh
+ * @param {GLTF.Mesh} meshDef
+ */
+
+
+ function updateMorphTargets( mesh, meshDef ) {
+
+ mesh.updateMorphTargets();
+
+ if ( meshDef.weights !== undefined ) {
+
+ for ( let i = 0, il = meshDef.weights.length; i < il; i ++ ) {
+
+ mesh.morphTargetInfluences[ i ] = meshDef.weights[ i ];
+
+ }
+
+ } // .extras has user-defined data, so check that .extras.targetNames is an array.
+
+
+ if ( meshDef.extras && Array.isArray( meshDef.extras.targetNames ) ) {
+
+ const targetNames = meshDef.extras.targetNames;
+
+ if ( mesh.morphTargetInfluences.length === targetNames.length ) {
+
+ mesh.morphTargetDictionary = {};
+
+ for ( let i = 0, il = targetNames.length; i < il; i ++ ) {
+
+ mesh.morphTargetDictionary[ targetNames[ i ] ] = i;
+
+ }
+
+ } else {
+
+ console.warn( 'THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.' );
+
+ }
+
+ }
+
+ }
+
+ function createPrimitiveKey( primitiveDef ) {
+
+ const dracoExtension = primitiveDef.extensions && primitiveDef.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ];
+ let geometryKey;
+
+ if ( dracoExtension ) {
+
+ geometryKey = 'draco:' + dracoExtension.bufferView + ':' + dracoExtension.indices + ':' + createAttributesKey( dracoExtension.attributes );
+
+ } else {
+
+ geometryKey = primitiveDef.indices + ':' + createAttributesKey( primitiveDef.attributes ) + ':' + primitiveDef.mode;
+
+ }
+
+ return geometryKey;
+
+ }
+
+ function createAttributesKey( attributes ) {
+
+ let attributesKey = '';
+ const keys = Object.keys( attributes ).sort();
+
+ for ( let i = 0, il = keys.length; i < il; i ++ ) {
+
+ attributesKey += keys[ i ] + ':' + attributes[ keys[ i ] ] + ';';
+
+ }
+
+ return attributesKey;
+
+ }
+
+ function getNormalizedComponentScale( constructor ) {
+
+ // Reference:
+ // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization#encoding-quantized-data
+ switch ( constructor ) {
+
+ case Int8Array:
+ return 1 / 127;
+
+ case Uint8Array:
+ return 1 / 255;
+
+ case Int16Array:
+ return 1 / 32767;
+
+ case Uint16Array:
+ return 1 / 65535;
+
+ default:
+ throw new Error( 'THREE.GLTFLoader: Unsupported normalized accessor component type.' );
+
+ }
+
+ }
+ /* GLTF PARSER */
+
+
+ class GLTFParser {
+
+ constructor( json = {}, options = {} ) {
+
+ this.json = json;
+ this.extensions = {};
+ this.plugins = {};
+ this.options = options; // loader object cache
+
+ this.cache = new GLTFRegistry(); // associations between Three.js objects and glTF elements
+
+ this.associations = new Map(); // THREE.BufferGeometry caching
+
+ this.primitiveCache = {}; // THREE.Object3D instance caches
+
+ this.meshCache = {
+ refs: {},
+ uses: {}
+ };
+ this.cameraCache = {
+ refs: {},
+ uses: {}
+ };
+ this.lightCache = {
+ refs: {},
+ uses: {}
+ }; // Track node names, to ensure no duplicates
+
+ this.nodeNamesUsed = {}; // Use an THREE.ImageBitmapLoader if imageBitmaps are supported. Moves much of the
+ // expensive work of uploading a texture to the GPU off the main thread.
+
+ if ( typeof createImageBitmap !== 'undefined' && /Firefox/.test( navigator.userAgent ) === false ) {
+
+ this.textureLoader = new THREE.ImageBitmapLoader( this.options.manager );
+
+ } else {
+
+ this.textureLoader = new THREE.TextureLoader( this.options.manager );
+
+ }
+
+ this.textureLoader.setCrossOrigin( this.options.crossOrigin );
+ this.textureLoader.setRequestHeader( this.options.requestHeader );
+ this.fileLoader = new THREE.FileLoader( this.options.manager );
+ this.fileLoader.setResponseType( 'arraybuffer' );
+
+ if ( this.options.crossOrigin === 'use-credentials' ) {
+
+ this.fileLoader.setWithCredentials( true );
+
+ }
+
+ }
+
+ setExtensions( extensions ) {
+
+ this.extensions = extensions;
+
+ }
+
+ setPlugins( plugins ) {
+
+ this.plugins = plugins;
+
+ }
+
+ parse( onLoad, onError ) {
+
+ const parser = this;
+ const json = this.json;
+ const extensions = this.extensions; // Clear the loader cache
+
+ this.cache.removeAll(); // Mark the special nodes/meshes in json for efficient parse
+
+ this._invokeAll( function ( ext ) {
+
+ return ext._markDefs && ext._markDefs();
+
+ } );
+
+ Promise.all( this._invokeAll( function ( ext ) {
+
+ return ext.beforeRoot && ext.beforeRoot();
+
+ } ) ).then( function () {
+
+ return Promise.all( [ parser.getDependencies( 'scene' ), parser.getDependencies( 'animation' ), parser.getDependencies( 'camera' ) ] );
+
+ } ).then( function ( dependencies ) {
+
+ const result = {
+ scene: dependencies[ 0 ][ json.scene || 0 ],
+ scenes: dependencies[ 0 ],
+ animations: dependencies[ 1 ],
+ cameras: dependencies[ 2 ],
+ asset: json.asset,
+ parser: parser,
+ userData: {}
+ };
+ addUnknownExtensionsToUserData( extensions, result, json );
+ assignExtrasToUserData( result, json );
+ Promise.all( parser._invokeAll( function ( ext ) {
+
+ return ext.afterRoot && ext.afterRoot( result );
+
+ } ) ).then( function () {
+
+ onLoad( result );
+
+ } );
+
+ } ).catch( onError );
+
+ }
+ /**
+ * Marks the special nodes/meshes in json for efficient parse.
+ */
+
+
+ _markDefs() {
+
+ const nodeDefs = this.json.nodes || [];
+ const skinDefs = this.json.skins || [];
+ const meshDefs = this.json.meshes || []; // Nothing in the node definition indicates whether it is a THREE.Bone or an
+ // THREE.Object3D. Use the skins' joint references to mark bones.
+
+ for ( let skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex ++ ) {
+
+ const joints = skinDefs[ skinIndex ].joints;
+
+ for ( let i = 0, il = joints.length; i < il; i ++ ) {
+
+ nodeDefs[ joints[ i ] ].isBone = true;
+
+ }
+
+ } // Iterate over all nodes, marking references to shared resources,
+ // as well as skeleton joints.
+
+
+ for ( let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex ++ ) {
+
+ const nodeDef = nodeDefs[ nodeIndex ];
+
+ if ( nodeDef.mesh !== undefined ) {
+
+ this._addNodeRef( this.meshCache, nodeDef.mesh ); // Nothing in the mesh definition indicates whether it is
+ // a THREE.SkinnedMesh or THREE.Mesh. Use the node's mesh reference
+ // to mark THREE.SkinnedMesh if node has skin.
+
+
+ if ( nodeDef.skin !== undefined ) {
+
+ meshDefs[ nodeDef.mesh ].isSkinnedMesh = true;
+
+ }
+
+ }
+
+ if ( nodeDef.camera !== undefined ) {
+
+ this._addNodeRef( this.cameraCache, nodeDef.camera );
+
+ }
+
+ }
+
+ }
+ /**
+ * Counts references to shared node / THREE.Object3D resources. These resources
+ * can be reused, or "instantiated", at multiple nodes in the scene
+ * hierarchy. THREE.Mesh, Camera, and Light instances are instantiated and must
+ * be marked. Non-scenegraph resources (like Materials, Geometries, and
+ * Textures) can be reused directly and are not marked here.
+ *
+ * Example: CesiumMilkTruck sample model reuses "Wheel" meshes.
+ */
+
+
+ _addNodeRef( cache, index ) {
+
+ if ( index === undefined ) return;
+
+ if ( cache.refs[ index ] === undefined ) {
+
+ cache.refs[ index ] = cache.uses[ index ] = 0;
+
+ }
+
+ cache.refs[ index ] ++;
+
+ }
+ /** Returns a reference to a shared resource, cloning it if necessary. */
+
+
+ _getNodeRef( cache, index, object ) {
+
+ if ( cache.refs[ index ] <= 1 ) return object;
+ const ref = object.clone();
+ ref.name += '_instance_' + cache.uses[ index ] ++;
+ return ref;
+
+ }
+
+ _invokeOne( func ) {
+
+ const extensions = Object.values( this.plugins );
+ extensions.push( this );
+
+ for ( let i = 0; i < extensions.length; i ++ ) {
+
+ const result = func( extensions[ i ] );
+ if ( result ) return result;
+
+ }
+
+ return null;
+
+ }
+
+ _invokeAll( func ) {
+
+ const extensions = Object.values( this.plugins );
+ extensions.unshift( this );
+ const pending = [];
+
+ for ( let i = 0; i < extensions.length; i ++ ) {
+
+ const result = func( extensions[ i ] );
+ if ( result ) pending.push( result );
+
+ }
+
+ return pending;
+
+ }
+ /**
+ * Requests the specified dependency asynchronously, with caching.
+ * @param {string} type
+ * @param {number} index
+ * @return {Promise<Object3D|Material|THREE.Texture|AnimationClip|ArrayBuffer|Object>}
+ */
+
+
+ getDependency( type, index ) {
+
+ const cacheKey = type + ':' + index;
+ let dependency = this.cache.get( cacheKey );
+
+ if ( ! dependency ) {
+
+ switch ( type ) {
+
+ case 'scene':
+ dependency = this.loadScene( index );
+ break;
+
+ case 'node':
+ dependency = this.loadNode( index );
+ break;
+
+ case 'mesh':
+ dependency = this._invokeOne( function ( ext ) {
+
+ return ext.loadMesh && ext.loadMesh( index );
+
+ } );
+ break;
+
+ case 'accessor':
+ dependency = this.loadAccessor( index );
+ break;
+
+ case 'bufferView':
+ dependency = this._invokeOne( function ( ext ) {
+
+ return ext.loadBufferView && ext.loadBufferView( index );
+
+ } );
+ break;
+
+ case 'buffer':
+ dependency = this.loadBuffer( index );
+ break;
+
+ case 'material':
+ dependency = this._invokeOne( function ( ext ) {
+
+ return ext.loadMaterial && ext.loadMaterial( index );
+
+ } );
+ break;
+
+ case 'texture':
+ dependency = this._invokeOne( function ( ext ) {
+
+ return ext.loadTexture && ext.loadTexture( index );
+
+ } );
+ break;
+
+ case 'skin':
+ dependency = this.loadSkin( index );
+ break;
+
+ case 'animation':
+ dependency = this.loadAnimation( index );
+ break;
+
+ case 'camera':
+ dependency = this.loadCamera( index );
+ break;
+
+ default:
+ throw new Error( 'Unknown type: ' + type );
+
+ }
+
+ this.cache.add( cacheKey, dependency );
+
+ }
+
+ return dependency;
+
+ }
+ /**
+ * Requests all dependencies of the specified type asynchronously, with caching.
+ * @param {string} type
+ * @return {Promise<Array<Object>>}
+ */
+
+
+ getDependencies( type ) {
+
+ let dependencies = this.cache.get( type );
+
+ if ( ! dependencies ) {
+
+ const parser = this;
+ const defs = this.json[ type + ( type === 'mesh' ? 'es' : 's' ) ] || [];
+ dependencies = Promise.all( defs.map( function ( def, index ) {
+
+ return parser.getDependency( type, index );
+
+ } ) );
+ this.cache.add( type, dependencies );
+
+ }
+
+ return dependencies;
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
+ * @param {number} bufferIndex
+ * @return {Promise<ArrayBuffer>}
+ */
+
+
+ loadBuffer( bufferIndex ) {
+
+ const bufferDef = this.json.buffers[ bufferIndex ];
+ const loader = this.fileLoader;
+
+ if ( bufferDef.type && bufferDef.type !== 'arraybuffer' ) {
+
+ throw new Error( 'THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.' );
+
+ } // If present, GLB container is required to be the first buffer.
+
+
+ if ( bufferDef.uri === undefined && bufferIndex === 0 ) {
+
+ return Promise.resolve( this.extensions[ EXTENSIONS.KHR_BINARY_GLTF ].body );
+
+ }
+
+ const options = this.options;
+ return new Promise( function ( resolve, reject ) {
+
+ loader.load( resolveURL( bufferDef.uri, options.path ), resolve, undefined, function () {
+
+ reject( new Error( 'THREE.GLTFLoader: Failed to load buffer "' + bufferDef.uri + '".' ) );
+
+ } );
+
+ } );
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
+ * @param {number} bufferViewIndex
+ * @return {Promise<ArrayBuffer>}
+ */
+
+
+ loadBufferView( bufferViewIndex ) {
+
+ const bufferViewDef = this.json.bufferViews[ bufferViewIndex ];
+ return this.getDependency( 'buffer', bufferViewDef.buffer ).then( function ( buffer ) {
+
+ const byteLength = bufferViewDef.byteLength || 0;
+ const byteOffset = bufferViewDef.byteOffset || 0;
+ return buffer.slice( byteOffset, byteOffset + byteLength );
+
+ } );
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors
+ * @param {number} accessorIndex
+ * @return {Promise<BufferAttribute|InterleavedBufferAttribute>}
+ */
+
+
+ loadAccessor( accessorIndex ) {
+
+ const parser = this;
+ const json = this.json;
+ const accessorDef = this.json.accessors[ accessorIndex ];
+
+ if ( accessorDef.bufferView === undefined && accessorDef.sparse === undefined ) {
+
+ // Ignore empty accessors, which may be used to declare runtime
+ // information about attributes coming from another source (e.g. Draco
+ // compression extension).
+ return Promise.resolve( null );
+
+ }
+
+ const pendingBufferViews = [];
+
+ if ( accessorDef.bufferView !== undefined ) {
+
+ pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.bufferView ) );
+
+ } else {
+
+ pendingBufferViews.push( null );
+
+ }
+
+ if ( accessorDef.sparse !== undefined ) {
+
+ pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.indices.bufferView ) );
+ pendingBufferViews.push( this.getDependency( 'bufferView', accessorDef.sparse.values.bufferView ) );
+
+ }
+
+ return Promise.all( pendingBufferViews ).then( function ( bufferViews ) {
+
+ const bufferView = bufferViews[ 0 ];
+ const itemSize = WEBGL_TYPE_SIZES[ accessorDef.type ];
+ const TypedArray = WEBGL_COMPONENT_TYPES[ accessorDef.componentType ]; // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
+
+ const elementBytes = TypedArray.BYTES_PER_ELEMENT;
+ const itemBytes = elementBytes * itemSize;
+ const byteOffset = accessorDef.byteOffset || 0;
+ const byteStride = accessorDef.bufferView !== undefined ? json.bufferViews[ accessorDef.bufferView ].byteStride : undefined;
+ const normalized = accessorDef.normalized === true;
+ let array, bufferAttribute; // The buffer is not interleaved if the stride is the item size in bytes.
+
+ if ( byteStride && byteStride !== itemBytes ) {
+
+ // Each "slice" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own THREE.InterleavedBuffer
+ // This makes sure that IBA.count reflects accessor.count properly
+ const ibSlice = Math.floor( byteOffset / byteStride );
+ const ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count;
+ let ib = parser.cache.get( ibCacheKey );
+
+ if ( ! ib ) {
+
+ array = new TypedArray( bufferView, ibSlice * byteStride, accessorDef.count * byteStride / elementBytes ); // Integer parameters to IB/IBA are in array elements, not bytes.
+
+ ib = new THREE.InterleavedBuffer( array, byteStride / elementBytes );
+ parser.cache.add( ibCacheKey, ib );
+
+ }
+
+ bufferAttribute = new THREE.InterleavedBufferAttribute( ib, itemSize, byteOffset % byteStride / elementBytes, normalized );
+
+ } else {
+
+ if ( bufferView === null ) {
+
+ array = new TypedArray( accessorDef.count * itemSize );
+
+ } else {
+
+ array = new TypedArray( bufferView, byteOffset, accessorDef.count * itemSize );
+
+ }
+
+ bufferAttribute = new THREE.BufferAttribute( array, itemSize, normalized );
+
+ } // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors
+
+
+ if ( accessorDef.sparse !== undefined ) {
+
+ const itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR;
+ const TypedArrayIndices = WEBGL_COMPONENT_TYPES[ accessorDef.sparse.indices.componentType ];
+ const byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0;
+ const byteOffsetValues = accessorDef.sparse.values.byteOffset || 0;
+ const sparseIndices = new TypedArrayIndices( bufferViews[ 1 ], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices );
+ const sparseValues = new TypedArray( bufferViews[ 2 ], byteOffsetValues, accessorDef.sparse.count * itemSize );
+
+ if ( bufferView !== null ) {
+
+ // Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes.
+ bufferAttribute = new THREE.BufferAttribute( bufferAttribute.array.slice(), bufferAttribute.itemSize, bufferAttribute.normalized );
+
+ }
+
+ for ( let i = 0, il = sparseIndices.length; i < il; i ++ ) {
+
+ const index = sparseIndices[ i ];
+ bufferAttribute.setX( index, sparseValues[ i * itemSize ] );
+ if ( itemSize >= 2 ) bufferAttribute.setY( index, sparseValues[ i * itemSize + 1 ] );
+ if ( itemSize >= 3 ) bufferAttribute.setZ( index, sparseValues[ i * itemSize + 2 ] );
+ if ( itemSize >= 4 ) bufferAttribute.setW( index, sparseValues[ i * itemSize + 3 ] );
+ if ( itemSize >= 5 ) throw new Error( 'THREE.GLTFLoader: Unsupported itemSize in sparse THREE.BufferAttribute.' );
+
+ }
+
+ }
+
+ return bufferAttribute;
+
+ } );
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures
+ * @param {number} textureIndex
+ * @return {Promise<THREE.Texture>}
+ */
+
+
+ loadTexture( textureIndex ) {
+
+ const json = this.json;
+ const options = this.options;
+ const textureDef = json.textures[ textureIndex ];
+ const source = json.images[ textureDef.source ];
+ let loader = this.textureLoader;
+
+ if ( source.uri ) {
+
+ const handler = options.manager.getHandler( source.uri );
+ if ( handler !== null ) loader = handler;
+
+ }
+
+ return this.loadTextureImage( textureIndex, source, loader );
+
+ }
+
+ loadTextureImage( textureIndex, source, loader ) {
+
+ const parser = this;
+ const json = this.json;
+ const options = this.options;
+ const textureDef = json.textures[ textureIndex ];
+ const URL = self.URL || self.webkitURL;
+ let sourceURI = source.uri;
+ let isObjectURL = false;
+ let hasAlpha = true;
+ if ( source.mimeType === 'image/jpeg' ) hasAlpha = false;
+
+ if ( source.bufferView !== undefined ) {
+
+ // Load binary image data from bufferView, if provided.
+ sourceURI = parser.getDependency( 'bufferView', source.bufferView ).then( function ( bufferView ) {
+
+ if ( source.mimeType === 'image/png' ) {
+
+ // Inspect the PNG 'IHDR' chunk to determine whether the image could have an
+ // alpha channel. This check is conservative β€” the image could have an alpha
+ // channel with all values == 1, and the indexed type (colorType == 3) only
+ // sometimes contains alpha.
+ //
+ // https://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header
+ const colorType = new DataView( bufferView, 25, 1 ).getUint8( 0, false );
+ hasAlpha = colorType === 6 || colorType === 4 || colorType === 3;
+
+ }
+
+ isObjectURL = true;
+ const blob = new Blob( [ bufferView ], {
+ type: source.mimeType
+ } );
+ sourceURI = URL.createObjectURL( blob );
+ return sourceURI;
+
+ } );
+
+ } else if ( source.uri === undefined ) {
+
+ throw new Error( 'THREE.GLTFLoader: Image ' + textureIndex + ' is missing URI and bufferView' );
+
+ }
+
+ return Promise.resolve( sourceURI ).then( function ( sourceURI ) {
+
+ return new Promise( function ( resolve, reject ) {
+
+ let onLoad = resolve;
+
+ if ( loader.isImageBitmapLoader === true ) {
+
+ onLoad = function ( imageBitmap ) {
+
+ resolve( new THREE.CanvasTexture( imageBitmap ) );
+
+ };
+
+ }
+
+ loader.load( resolveURL( sourceURI, options.path ), onLoad, undefined, reject );
+
+ } );
+
+ } ).then( function ( texture ) {
+
+ // Clean up resources and configure Texture.
+ if ( isObjectURL === true ) {
+
+ URL.revokeObjectURL( sourceURI );
+
+ }
+
+ texture.flipY = false;
+ if ( textureDef.name ) texture.name = textureDef.name; // When there is definitely no alpha channel in the texture, set THREE.RGBFormat to save space.
+
+ if ( ! hasAlpha ) texture.format = THREE.RGBFormat;
+ const samplers = json.samplers || {};
+ const sampler = samplers[ textureDef.sampler ] || {};
+ texture.magFilter = WEBGL_FILTERS[ sampler.magFilter ] || THREE.LinearFilter;
+ texture.minFilter = WEBGL_FILTERS[ sampler.minFilter ] || THREE.LinearMipmapLinearFilter;
+ texture.wrapS = WEBGL_WRAPPINGS[ sampler.wrapS ] || THREE.RepeatWrapping;
+ texture.wrapT = WEBGL_WRAPPINGS[ sampler.wrapT ] || THREE.RepeatWrapping;
+ parser.associations.set( texture, {
+ type: 'textures',
+ index: textureIndex
+ } );
+ return texture;
+
+ } );
+
+ }
+ /**
+ * Asynchronously assigns a texture to the given material parameters.
+ * @param {Object} materialParams
+ * @param {string} mapName
+ * @param {Object} mapDef
+ * @return {Promise}
+ */
+
+
+ assignTexture( materialParams, mapName, mapDef ) {
+
+ const parser = this;
+ return this.getDependency( 'texture', mapDef.index ).then( function ( texture ) {
+
+ // Materials sample aoMap from UV set 1 and other maps from UV set 0 - this can't be configured
+ // However, we will copy UV set 0 to UV set 1 on demand for aoMap
+ if ( mapDef.texCoord !== undefined && mapDef.texCoord != 0 && ! ( mapName === 'aoMap' && mapDef.texCoord == 1 ) ) {
+
+ console.warn( 'THREE.GLTFLoader: Custom UV set ' + mapDef.texCoord + ' for texture ' + mapName + ' not yet supported.' );
+
+ }
+
+ if ( parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] ) {
+
+ const transform = mapDef.extensions !== undefined ? mapDef.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ] : undefined;
+
+ if ( transform ) {
+
+ const gltfReference = parser.associations.get( texture );
+ texture = parser.extensions[ EXTENSIONS.KHR_TEXTURE_TRANSFORM ].extendTexture( texture, transform );
+ parser.associations.set( texture, gltfReference );
+
+ }
+
+ }
+
+ materialParams[ mapName ] = texture;
+
+ } );
+
+ }
+ /**
+ * Assigns final material to a THREE.Mesh, THREE.Line, or THREE.Points instance. The instance
+ * already has a material (generated from the glTF material options alone)
+ * but reuse of the same glTF material may require multiple threejs materials
+ * to accommodate different primitive types, defines, etc. New materials will
+ * be created if necessary, and reused from a cache.
+ * @param {Object3D} mesh THREE.Mesh, THREE.Line, or THREE.Points instance.
+ */
+
+
+ assignFinalMaterial( mesh ) {
+
+ const geometry = mesh.geometry;
+ let material = mesh.material;
+ const useVertexTangents = geometry.attributes.tangent !== undefined;
+ const useVertexColors = geometry.attributes.color !== undefined;
+ const useFlatShading = geometry.attributes.normal === undefined;
+ const useSkinning = mesh.isSkinnedMesh === true;
+ const useMorphTargets = Object.keys( geometry.morphAttributes ).length > 0;
+ const useMorphNormals = useMorphTargets && geometry.morphAttributes.normal !== undefined;
+
+ if ( mesh.isPoints ) {
+
+ const cacheKey = 'PointsMaterial:' + material.uuid;
+ let pointsMaterial = this.cache.get( cacheKey );
+
+ if ( ! pointsMaterial ) {
+
+ pointsMaterial = new THREE.PointsMaterial();
+ THREE.Material.prototype.copy.call( pointsMaterial, material );
+ pointsMaterial.color.copy( material.color );
+ pointsMaterial.map = material.map;
+ pointsMaterial.sizeAttenuation = false; // glTF spec says points should be 1px
+
+ this.cache.add( cacheKey, pointsMaterial );
+
+ }
+
+ material = pointsMaterial;
+
+ } else if ( mesh.isLine ) {
+
+ const cacheKey = 'LineBasicMaterial:' + material.uuid;
+ let lineMaterial = this.cache.get( cacheKey );
+
+ if ( ! lineMaterial ) {
+
+ lineMaterial = new THREE.LineBasicMaterial();
+ THREE.Material.prototype.copy.call( lineMaterial, material );
+ lineMaterial.color.copy( material.color );
+ this.cache.add( cacheKey, lineMaterial );
+
+ }
+
+ material = lineMaterial;
+
+ } // Clone the material if it will be modified
+
+
+ if ( useVertexTangents || useVertexColors || useFlatShading || useSkinning || useMorphTargets ) {
+
+ let cacheKey = 'ClonedMaterial:' + material.uuid + ':';
+ if ( material.isGLTFSpecularGlossinessMaterial ) cacheKey += 'specular-glossiness:';
+ if ( useSkinning ) cacheKey += 'skinning:';
+ if ( useVertexTangents ) cacheKey += 'vertex-tangents:';
+ if ( useVertexColors ) cacheKey += 'vertex-colors:';
+ if ( useFlatShading ) cacheKey += 'flat-shading:';
+ if ( useMorphTargets ) cacheKey += 'morph-targets:';
+ if ( useMorphNormals ) cacheKey += 'morph-normals:';
+ let cachedMaterial = this.cache.get( cacheKey );
+
+ if ( ! cachedMaterial ) {
+
+ cachedMaterial = material.clone();
+ if ( useSkinning ) cachedMaterial.skinning = true;
+ if ( useVertexColors ) cachedMaterial.vertexColors = true;
+ if ( useFlatShading ) cachedMaterial.flatShading = true;
+ if ( useMorphTargets ) cachedMaterial.morphTargets = true;
+ if ( useMorphNormals ) cachedMaterial.morphNormals = true;
+
+ if ( useVertexTangents ) {
+
+ cachedMaterial.vertexTangents = true; // https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
+
+ if ( cachedMaterial.normalScale ) cachedMaterial.normalScale.y *= - 1;
+ if ( cachedMaterial.clearcoatNormalScale ) cachedMaterial.clearcoatNormalScale.y *= - 1;
+
+ }
+
+ this.cache.add( cacheKey, cachedMaterial );
+ this.associations.set( cachedMaterial, this.associations.get( material ) );
+
+ }
+
+ material = cachedMaterial;
+
+ } // workarounds for mesh and geometry
+
+
+ if ( material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined ) {
+
+ geometry.setAttribute( 'uv2', geometry.attributes.uv );
+
+ }
+
+ mesh.material = material;
+
+ }
+
+ getMaterialType( ) {
+
+ return THREE.MeshStandardMaterial;
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
+ * @param {number} materialIndex
+ * @return {Promise<Material>}
+ */
+
+
+ loadMaterial( materialIndex ) {
+
+ const parser = this;
+ const json = this.json;
+ const extensions = this.extensions;
+ const materialDef = json.materials[ materialIndex ];
+ let materialType;
+ const materialParams = {};
+ const materialExtensions = materialDef.extensions || {};
+ const pending = [];
+
+ if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ] ) {
+
+ const sgExtension = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ];
+ materialType = sgExtension.getMaterialType();
+ pending.push( sgExtension.extendParams( materialParams, materialDef, parser ) );
+
+ } else if ( materialExtensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ] ) {
+
+ const kmuExtension = extensions[ EXTENSIONS.KHR_MATERIALS_UNLIT ];
+ materialType = kmuExtension.getMaterialType();
+ pending.push( kmuExtension.extendParams( materialParams, materialDef, parser ) );
+
+ } else {
+
+ // Specification:
+ // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material
+ const metallicRoughness = materialDef.pbrMetallicRoughness || {};
+ materialParams.color = new THREE.Color( 1.0, 1.0, 1.0 );
+ materialParams.opacity = 1.0;
+
+ if ( Array.isArray( metallicRoughness.baseColorFactor ) ) {
+
+ const array = metallicRoughness.baseColorFactor;
+ materialParams.color.fromArray( array );
+ materialParams.opacity = array[ 3 ];
+
+ }
+
+ if ( metallicRoughness.baseColorTexture !== undefined ) {
+
+ pending.push( parser.assignTexture( materialParams, 'map', metallicRoughness.baseColorTexture ) );
+
+ }
+
+ materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0;
+ materialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0;
+
+ if ( metallicRoughness.metallicRoughnessTexture !== undefined ) {
+
+ pending.push( parser.assignTexture( materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture ) );
+ pending.push( parser.assignTexture( materialParams, 'roughnessMap', metallicRoughness.metallicRoughnessTexture ) );
+
+ }
+
+ materialType = this._invokeOne( function ( ext ) {
+
+ return ext.getMaterialType && ext.getMaterialType( materialIndex );
+
+ } );
+ pending.push( Promise.all( this._invokeAll( function ( ext ) {
+
+ return ext.extendMaterialParams && ext.extendMaterialParams( materialIndex, materialParams );
+
+ } ) ) );
+
+ }
+
+ if ( materialDef.doubleSided === true ) {
+
+ materialParams.side = THREE.DoubleSide;
+
+ }
+
+ const alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE;
+
+ if ( alphaMode === ALPHA_MODES.BLEND ) {
+
+ materialParams.transparent = true; // See: https://github.com/mrdoob/three.js/issues/17706
+
+ materialParams.depthWrite = false;
+
+ } else {
+
+ materialParams.transparent = false;
+
+ if ( alphaMode === ALPHA_MODES.MASK ) {
+
+ materialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5;
+
+ }
+
+ }
+
+ if ( materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {
+
+ pending.push( parser.assignTexture( materialParams, 'normalMap', materialDef.normalTexture ) ); // https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
+
+ materialParams.normalScale = new THREE.Vector2( 1, - 1 );
+
+ if ( materialDef.normalTexture.scale !== undefined ) {
+
+ materialParams.normalScale.set( materialDef.normalTexture.scale, - materialDef.normalTexture.scale );
+
+ }
+
+ }
+
+ if ( materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {
+
+ pending.push( parser.assignTexture( materialParams, 'aoMap', materialDef.occlusionTexture ) );
+
+ if ( materialDef.occlusionTexture.strength !== undefined ) {
+
+ materialParams.aoMapIntensity = materialDef.occlusionTexture.strength;
+
+ }
+
+ }
+
+ if ( materialDef.emissiveFactor !== undefined && materialType !== THREE.MeshBasicMaterial ) {
+
+ materialParams.emissive = new THREE.Color().fromArray( materialDef.emissiveFactor );
+
+ }
+
+ if ( materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial ) {
+
+ pending.push( parser.assignTexture( materialParams, 'emissiveMap', materialDef.emissiveTexture ) );
+
+ }
+
+ return Promise.all( pending ).then( function () {
+
+ let material;
+
+ if ( materialType === GLTFMeshStandardSGMaterial ) {
+
+ material = extensions[ EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS ].createMaterial( materialParams );
+
+ } else {
+
+ material = new materialType( materialParams );
+
+ }
+
+ if ( materialDef.name ) material.name = materialDef.name; // baseColorTexture, emissiveTexture, and specularGlossinessTexture use sRGB encoding.
+
+ if ( material.map ) material.map.encoding = THREE.sRGBEncoding;
+ if ( material.emissiveMap ) material.emissiveMap.encoding = THREE.sRGBEncoding;
+ assignExtrasToUserData( material, materialDef );
+ parser.associations.set( material, {
+ type: 'materials',
+ index: materialIndex
+ } );
+ if ( materialDef.extensions ) addUnknownExtensionsToUserData( extensions, material, materialDef );
+ return material;
+
+ } );
+
+ }
+ /** When THREE.Object3D instances are targeted by animation, they need unique names. */
+
+
+ createUniqueName( originalName ) {
+
+ const sanitizedName = THREE.PropertyBinding.sanitizeNodeName( originalName || '' );
+ let name = sanitizedName;
+
+ for ( let i = 1; this.nodeNamesUsed[ name ]; ++ i ) {
+
+ name = sanitizedName + '_' + i;
+
+ }
+
+ this.nodeNamesUsed[ name ] = true;
+ return name;
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry
+ *
+ * Creates BufferGeometries from primitives.
+ *
+ * @param {Array<GLTF.Primitive>} primitives
+ * @return {Promise<Array<BufferGeometry>>}
+ */
+
+
+ loadGeometries( primitives ) {
+
+ const parser = this;
+ const extensions = this.extensions;
+ const cache = this.primitiveCache;
+
+ function createDracoPrimitive( primitive ) {
+
+ return extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ].decodePrimitive( primitive, parser ).then( function ( geometry ) {
+
+ return addPrimitiveAttributes( geometry, primitive, parser );
+
+ } );
+
+ }
+
+ const pending = [];
+
+ for ( let i = 0, il = primitives.length; i < il; i ++ ) {
+
+ const primitive = primitives[ i ];
+ const cacheKey = createPrimitiveKey( primitive ); // See if we've already created this geometry
+
+ const cached = cache[ cacheKey ];
+
+ if ( cached ) {
+
+ // Use the cached geometry if it exists
+ pending.push( cached.promise );
+
+ } else {
+
+ let geometryPromise;
+
+ if ( primitive.extensions && primitive.extensions[ EXTENSIONS.KHR_DRACO_MESH_COMPRESSION ] ) {
+
+ // Use DRACO geometry if available
+ geometryPromise = createDracoPrimitive( primitive );
+
+ } else {
+
+ // Otherwise create a new geometry
+ geometryPromise = addPrimitiveAttributes( new THREE.BufferGeometry(), primitive, parser );
+
+ } // Cache this geometry
+
+
+ cache[ cacheKey ] = {
+ primitive: primitive,
+ promise: geometryPromise
+ };
+ pending.push( geometryPromise );
+
+ }
+
+ }
+
+ return Promise.all( pending );
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes
+ * @param {number} meshIndex
+ * @return {Promise<Group|Mesh|SkinnedMesh>}
+ */
+
+
+ loadMesh( meshIndex ) {
+
+ const parser = this;
+ const json = this.json;
+ const extensions = this.extensions;
+ const meshDef = json.meshes[ meshIndex ];
+ const primitives = meshDef.primitives;
+ const pending = [];
+
+ for ( let i = 0, il = primitives.length; i < il; i ++ ) {
+
+ const material = primitives[ i ].material === undefined ? createDefaultMaterial( this.cache ) : this.getDependency( 'material', primitives[ i ].material );
+ pending.push( material );
+
+ }
+
+ pending.push( parser.loadGeometries( primitives ) );
+ return Promise.all( pending ).then( function ( results ) {
+
+ const materials = results.slice( 0, results.length - 1 );
+ const geometries = results[ results.length - 1 ];
+ const meshes = [];
+
+ for ( let i = 0, il = geometries.length; i < il; i ++ ) {
+
+ const geometry = geometries[ i ];
+ const primitive = primitives[ i ]; // 1. create THREE.Mesh
+
+ let mesh;
+ const material = materials[ i ];
+
+ if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLES || primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP || primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN || primitive.mode === undefined ) {
+
+ // .isSkinnedMesh isn't in glTF spec. See ._markDefs()
+ mesh = meshDef.isSkinnedMesh === true ? new THREE.SkinnedMesh( geometry, material ) : new THREE.Mesh( geometry, material );
+
+ if ( mesh.isSkinnedMesh === true && ! mesh.geometry.attributes.skinWeight.normalized ) {
+
+ // we normalize floating point skin weight array to fix malformed assets (see #15319)
+ // it's important to skip this for non-float32 data since normalizeSkinWeights assumes non-normalized inputs
+ mesh.normalizeSkinWeights();
+
+ }
+
+ if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ) {
+
+ mesh.geometry = toTrianglesDrawMode( mesh.geometry, THREE.TriangleStripDrawMode );
+
+ } else if ( primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ) {
+
+ mesh.geometry = toTrianglesDrawMode( mesh.geometry, THREE.TriangleFanDrawMode );
+
+ }
+
+ } else if ( primitive.mode === WEBGL_CONSTANTS.LINES ) {
+
+ mesh = new THREE.LineSegments( geometry, material );
+
+ } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_STRIP ) {
+
+ mesh = new THREE.Line( geometry, material );
+
+ } else if ( primitive.mode === WEBGL_CONSTANTS.LINE_LOOP ) {
+
+ mesh = new THREE.LineLoop( geometry, material );
+
+ } else if ( primitive.mode === WEBGL_CONSTANTS.POINTS ) {
+
+ mesh = new THREE.Points( geometry, material );
+
+ } else {
+
+ throw new Error( 'THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode );
+
+ }
+
+ if ( Object.keys( mesh.geometry.morphAttributes ).length > 0 ) {
+
+ updateMorphTargets( mesh, meshDef );
+
+ }
+
+ mesh.name = parser.createUniqueName( meshDef.name || 'mesh_' + meshIndex );
+ assignExtrasToUserData( mesh, meshDef );
+ if ( primitive.extensions ) addUnknownExtensionsToUserData( extensions, mesh, primitive );
+ parser.assignFinalMaterial( mesh );
+ meshes.push( mesh );
+
+ }
+
+ if ( meshes.length === 1 ) {
+
+ return meshes[ 0 ];
+
+ }
+
+ const group = new THREE.Group();
+
+ for ( let i = 0, il = meshes.length; i < il; i ++ ) {
+
+ group.add( meshes[ i ] );
+
+ }
+
+ return group;
+
+ } );
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras
+ * @param {number} cameraIndex
+ * @return {Promise<THREE.Camera>}
+ */
+
+
+ loadCamera( cameraIndex ) {
+
+ let camera;
+ const cameraDef = this.json.cameras[ cameraIndex ];
+ const params = cameraDef[ cameraDef.type ];
+
+ if ( ! params ) {
+
+ console.warn( 'THREE.GLTFLoader: Missing camera parameters.' );
+ return;
+
+ }
+
+ if ( cameraDef.type === 'perspective' ) {
+
+ camera = new THREE.PerspectiveCamera( THREE.MathUtils.radToDeg( params.yfov ), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6 );
+
+ } else if ( cameraDef.type === 'orthographic' ) {
+
+ camera = new THREE.OrthographicCamera( - params.xmag, params.xmag, params.ymag, - params.ymag, params.znear, params.zfar );
+
+ }
+
+ if ( cameraDef.name ) camera.name = this.createUniqueName( cameraDef.name );
+ assignExtrasToUserData( camera, cameraDef );
+ return Promise.resolve( camera );
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins
+ * @param {number} skinIndex
+ * @return {Promise<Object>}
+ */
+
+
+ loadSkin( skinIndex ) {
+
+ const skinDef = this.json.skins[ skinIndex ];
+ const skinEntry = {
+ joints: skinDef.joints
+ };
+
+ if ( skinDef.inverseBindMatrices === undefined ) {
+
+ return Promise.resolve( skinEntry );
+
+ }
+
+ return this.getDependency( 'accessor', skinDef.inverseBindMatrices ).then( function ( accessor ) {
+
+ skinEntry.inverseBindMatrices = accessor;
+ return skinEntry;
+
+ } );
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations
+ * @param {number} animationIndex
+ * @return {Promise<AnimationClip>}
+ */
+
+
+ loadAnimation( animationIndex ) {
+
+ const json = this.json;
+ const animationDef = json.animations[ animationIndex ];
+ const pendingNodes = [];
+ const pendingInputAccessors = [];
+ const pendingOutputAccessors = [];
+ const pendingSamplers = [];
+ const pendingTargets = [];
+
+ for ( let i = 0, il = animationDef.channels.length; i < il; i ++ ) {
+
+ const channel = animationDef.channels[ i ];
+ const sampler = animationDef.samplers[ channel.sampler ];
+ const target = channel.target;
+ const name = target.node !== undefined ? target.node : target.id; // NOTE: target.id is deprecated.
+
+ const input = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.input ] : sampler.input;
+ const output = animationDef.parameters !== undefined ? animationDef.parameters[ sampler.output ] : sampler.output;
+ pendingNodes.push( this.getDependency( 'node', name ) );
+ pendingInputAccessors.push( this.getDependency( 'accessor', input ) );
+ pendingOutputAccessors.push( this.getDependency( 'accessor', output ) );
+ pendingSamplers.push( sampler );
+ pendingTargets.push( target );
+
+ }
+
+ return Promise.all( [ Promise.all( pendingNodes ), Promise.all( pendingInputAccessors ), Promise.all( pendingOutputAccessors ), Promise.all( pendingSamplers ), Promise.all( pendingTargets ) ] ).then( function ( dependencies ) {
+
+ const nodes = dependencies[ 0 ];
+ const inputAccessors = dependencies[ 1 ];
+ const outputAccessors = dependencies[ 2 ];
+ const samplers = dependencies[ 3 ];
+ const targets = dependencies[ 4 ];
+ const tracks = [];
+
+ for ( let i = 0, il = nodes.length; i < il; i ++ ) {
+
+ const node = nodes[ i ];
+ const inputAccessor = inputAccessors[ i ];
+ const outputAccessor = outputAccessors[ i ];
+ const sampler = samplers[ i ];
+ const target = targets[ i ];
+ if ( node === undefined ) continue;
+ node.updateMatrix();
+ node.matrixAutoUpdate = true;
+ let TypedKeyframeTrack;
+
+ switch ( PATH_PROPERTIES[ target.path ] ) {
+
+ case PATH_PROPERTIES.weights:
+ TypedKeyframeTrack = THREE.NumberKeyframeTrack;
+ break;
+
+ case PATH_PROPERTIES.rotation:
+ TypedKeyframeTrack = THREE.QuaternionKeyframeTrack;
+ break;
+
+ case PATH_PROPERTIES.position:
+ case PATH_PROPERTIES.scale:
+ default:
+ TypedKeyframeTrack = THREE.VectorKeyframeTrack;
+ break;
+
+ }
+
+ const targetName = node.name ? node.name : node.uuid;
+ const interpolation = sampler.interpolation !== undefined ? INTERPOLATION[ sampler.interpolation ] : THREE.InterpolateLinear;
+ const targetNames = [];
+
+ if ( PATH_PROPERTIES[ target.path ] === PATH_PROPERTIES.weights ) {
+
+ // Node may be a THREE.Group (glTF mesh with several primitives) or a THREE.Mesh.
+ node.traverse( function ( object ) {
+
+ if ( object.isMesh === true && object.morphTargetInfluences ) {
+
+ targetNames.push( object.name ? object.name : object.uuid );
+
+ }
+
+ } );
+
+ } else {
+
+ targetNames.push( targetName );
+
+ }
+
+ let outputArray = outputAccessor.array;
+
+ if ( outputAccessor.normalized ) {
+
+ const scale = getNormalizedComponentScale( outputArray.constructor );
+ const scaled = new Float32Array( outputArray.length );
+
+ for ( let j = 0, jl = outputArray.length; j < jl; j ++ ) {
+
+ scaled[ j ] = outputArray[ j ] * scale;
+
+ }
+
+ outputArray = scaled;
+
+ }
+
+ for ( let j = 0, jl = targetNames.length; j < jl; j ++ ) {
+
+ const track = new TypedKeyframeTrack( targetNames[ j ] + '.' + PATH_PROPERTIES[ target.path ], inputAccessor.array, outputArray, interpolation ); // Override interpolation with custom factory method.
+
+ if ( sampler.interpolation === 'CUBICSPLINE' ) {
+
+ track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline( result ) {
+
+ // A CUBICSPLINE keyframe in glTF has three output values for each input value,
+ // representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize()
+ // must be divided by three to get the interpolant's sampleSize argument.
+ return new GLTFCubicSplineInterpolant( this.times, this.values, this.getValueSize() / 3, result );
+
+ }; // Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.
+
+
+ track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true;
+
+ }
+
+ tracks.push( track );
+
+ }
+
+ }
+
+ const name = animationDef.name ? animationDef.name : 'animation_' + animationIndex;
+ return new THREE.AnimationClip( name, undefined, tracks );
+
+ } );
+
+ }
+
+ createNodeMesh( nodeIndex ) {
+
+ const json = this.json;
+ const parser = this;
+ const nodeDef = json.nodes[ nodeIndex ];
+ if ( nodeDef.mesh === undefined ) return null;
+ return parser.getDependency( 'mesh', nodeDef.mesh ).then( function ( mesh ) {
+
+ const node = parser._getNodeRef( parser.meshCache, nodeDef.mesh, mesh ); // if weights are provided on the node, override weights on the mesh.
+
+
+ if ( nodeDef.weights !== undefined ) {
+
+ node.traverse( function ( o ) {
+
+ if ( ! o.isMesh ) return;
+
+ for ( let i = 0, il = nodeDef.weights.length; i < il; i ++ ) {
+
+ o.morphTargetInfluences[ i ] = nodeDef.weights[ i ];
+
+ }
+
+ } );
+
+ }
+
+ return node;
+
+ } );
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy
+ * @param {number} nodeIndex
+ * @return {Promise<Object3D>}
+ */
+
+
+ loadNode( nodeIndex ) {
+
+ const json = this.json;
+ const extensions = this.extensions;
+ const parser = this;
+ const nodeDef = json.nodes[ nodeIndex ]; // reserve node's name before its dependencies, so the root has the intended name.
+
+ const nodeName = nodeDef.name ? parser.createUniqueName( nodeDef.name ) : '';
+ return function () {
+
+ const pending = [];
+
+ const meshPromise = parser._invokeOne( function ( ext ) {
+
+ return ext.createNodeMesh && ext.createNodeMesh( nodeIndex );
+
+ } );
+
+ if ( meshPromise ) {
+
+ pending.push( meshPromise );
+
+ }
+
+ if ( nodeDef.camera !== undefined ) {
+
+ pending.push( parser.getDependency( 'camera', nodeDef.camera ).then( function ( camera ) {
+
+ return parser._getNodeRef( parser.cameraCache, nodeDef.camera, camera );
+
+ } ) );
+
+ }
+
+ parser._invokeAll( function ( ext ) {
+
+ return ext.createNodeAttachment && ext.createNodeAttachment( nodeIndex );
+
+ } ).forEach( function ( promise ) {
+
+ pending.push( promise );
+
+ } );
+
+ return Promise.all( pending );
+
+ }().then( function ( objects ) {
+
+ let node; // .isBone isn't in glTF spec. See ._markDefs
+
+ if ( nodeDef.isBone === true ) {
+
+ node = new THREE.Bone();
+
+ } else if ( objects.length > 1 ) {
+
+ node = new THREE.Group();
+
+ } else if ( objects.length === 1 ) {
+
+ node = objects[ 0 ];
+
+ } else {
+
+ node = new THREE.Object3D();
+
+ }
+
+ if ( node !== objects[ 0 ] ) {
+
+ for ( let i = 0, il = objects.length; i < il; i ++ ) {
+
+ node.add( objects[ i ] );
+
+ }
+
+ }
+
+ if ( nodeDef.name ) {
+
+ node.userData.name = nodeDef.name;
+ node.name = nodeName;
+
+ }
+
+ assignExtrasToUserData( node, nodeDef );
+ if ( nodeDef.extensions ) addUnknownExtensionsToUserData( extensions, node, nodeDef );
+
+ if ( nodeDef.matrix !== undefined ) {
+
+ const matrix = new THREE.Matrix4();
+ matrix.fromArray( nodeDef.matrix );
+ node.applyMatrix4( matrix );
+
+ } else {
+
+ if ( nodeDef.translation !== undefined ) {
+
+ node.position.fromArray( nodeDef.translation );
+
+ }
+
+ if ( nodeDef.rotation !== undefined ) {
+
+ node.quaternion.fromArray( nodeDef.rotation );
+
+ }
+
+ if ( nodeDef.scale !== undefined ) {
+
+ node.scale.fromArray( nodeDef.scale );
+
+ }
+
+ }
+
+ parser.associations.set( node, {
+ type: 'nodes',
+ index: nodeIndex
+ } );
+ return node;
+
+ } );
+
+ }
+ /**
+ * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes
+ * @param {number} sceneIndex
+ * @return {Promise<Group>}
+ */
+
+
+ loadScene( sceneIndex ) {
+
+ const json = this.json;
+ const extensions = this.extensions;
+ const sceneDef = this.json.scenes[ sceneIndex ];
+ const parser = this; // THREE.Loader returns THREE.Group, not Scene.
+ // See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172
+
+ const scene = new THREE.Group();
+ if ( sceneDef.name ) scene.name = parser.createUniqueName( sceneDef.name );
+ assignExtrasToUserData( scene, sceneDef );
+ if ( sceneDef.extensions ) addUnknownExtensionsToUserData( extensions, scene, sceneDef );
+ const nodeIds = sceneDef.nodes || [];
+ const pending = [];
+
+ for ( let i = 0, il = nodeIds.length; i < il; i ++ ) {
+
+ pending.push( buildNodeHierachy( nodeIds[ i ], scene, json, parser ) );
+
+ }
+
+ return Promise.all( pending ).then( function () {
+
+ return scene;
+
+ } );
+
+ }
+
+ }
+
+ function buildNodeHierachy( nodeId, parentObject, json, parser ) {
+
+ const nodeDef = json.nodes[ nodeId ];
+ return parser.getDependency( 'node', nodeId ).then( function ( node ) {
+
+ if ( nodeDef.skin === undefined ) return node; // build skeleton here as well
+
+ let skinEntry;
+ return parser.getDependency( 'skin', nodeDef.skin ).then( function ( skin ) {
+
+ skinEntry = skin;
+ const pendingJoints = [];
+
+ for ( let i = 0, il = skinEntry.joints.length; i < il; i ++ ) {
+
+ pendingJoints.push( parser.getDependency( 'node', skinEntry.joints[ i ] ) );
+
+ }
+
+ return Promise.all( pendingJoints );
+
+ } ).then( function ( jointNodes ) {
+
+ node.traverse( function ( mesh ) {
+
+ if ( ! mesh.isMesh ) return;
+ const bones = [];
+ const boneInverses = [];
+
+ for ( let j = 0, jl = jointNodes.length; j < jl; j ++ ) {
+
+ const jointNode = jointNodes[ j ];
+
+ if ( jointNode ) {
+
+ bones.push( jointNode );
+ const mat = new THREE.Matrix4();
+
+ if ( skinEntry.inverseBindMatrices !== undefined ) {
+
+ mat.fromArray( skinEntry.inverseBindMatrices.array, j * 16 );
+
+ }
+
+ boneInverses.push( mat );
+
+ } else {
+
+ console.warn( 'THREE.GLTFLoader: Joint "%s" could not be found.', skinEntry.joints[ j ] );
+
+ }
+
+ }
+
+ mesh.bind( new THREE.Skeleton( bones, boneInverses ), mesh.matrixWorld );
+
+ } );
+ return node;
+
+ } );
+
+ } ).then( function ( node ) {
+
+ // build node hierachy
+ parentObject.add( node );
+ const pending = [];
+
+ if ( nodeDef.children ) {
+
+ const children = nodeDef.children;
+
+ for ( let i = 0, il = children.length; i < il; i ++ ) {
+
+ const child = children[ i ];
+ pending.push( buildNodeHierachy( child, node, json, parser ) );
+
+ }
+
+ }
+
+ return Promise.all( pending );
+
+ } );
+
+ }
+ /**
+ * @param {BufferGeometry} geometry
+ * @param {GLTF.Primitive} primitiveDef
+ * @param {GLTFParser} parser
+ */
+
+
+ function computeBounds( geometry, primitiveDef, parser ) {
+
+ const attributes = primitiveDef.attributes;
+ const box = new THREE.Box3();
+
+ if ( attributes.POSITION !== undefined ) {
+
+ const accessor = parser.json.accessors[ attributes.POSITION ];
+ const min = accessor.min;
+ const max = accessor.max; // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
+
+ if ( min !== undefined && max !== undefined ) {
+
+ box.set( new THREE.Vector3( min[ 0 ], min[ 1 ], min[ 2 ] ), new THREE.Vector3( max[ 0 ], max[ 1 ], max[ 2 ] ) );
+
+ if ( accessor.normalized ) {
+
+ const boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );
+ box.min.multiplyScalar( boxScale );
+ box.max.multiplyScalar( boxScale );
+
+ }
+
+ } else {
+
+ console.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' );
+ return;
+
+ }
+
+ } else {
+
+ return;
+
+ }
+
+ const targets = primitiveDef.targets;
+
+ if ( targets !== undefined ) {
+
+ const maxDisplacement = new THREE.Vector3();
+ const vector = new THREE.Vector3();
+
+ for ( let i = 0, il = targets.length; i < il; i ++ ) {
+
+ const target = targets[ i ];
+
+ if ( target.POSITION !== undefined ) {
+
+ const accessor = parser.json.accessors[ target.POSITION ];
+ const min = accessor.min;
+ const max = accessor.max; // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
+
+ if ( min !== undefined && max !== undefined ) {
+
+ // we need to get max of absolute components because target weight is [-1,1]
+ vector.setX( Math.max( Math.abs( min[ 0 ] ), Math.abs( max[ 0 ] ) ) );
+ vector.setY( Math.max( Math.abs( min[ 1 ] ), Math.abs( max[ 1 ] ) ) );
+ vector.setZ( Math.max( Math.abs( min[ 2 ] ), Math.abs( max[ 2 ] ) ) );
+
+ if ( accessor.normalized ) {
+
+ const boxScale = getNormalizedComponentScale( WEBGL_COMPONENT_TYPES[ accessor.componentType ] );
+ vector.multiplyScalar( boxScale );
+
+ } // Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative
+ // to assume that each target can have a max weight of 1. However, for some use cases - notably, when morph targets
+ // are used to implement key-frame animations and as such only two are active at a time - this results in very large
+ // boxes. So for now we make a box that's sometimes a touch too small but is hopefully mostly of reasonable size.
+
+
+ maxDisplacement.max( vector );
+
+ } else {
+
+ console.warn( 'THREE.GLTFLoader: Missing min/max properties for accessor POSITION.' );
+
+ }
+
+ }
+
+ } // As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets.
+
+
+ box.expandByVector( maxDisplacement );
+
+ }
+
+ geometry.boundingBox = box;
+ const sphere = new THREE.Sphere();
+ box.getCenter( sphere.center );
+ sphere.radius = box.min.distanceTo( box.max ) / 2;
+ geometry.boundingSphere = sphere;
+
+ }
+ /**
+ * @param {BufferGeometry} geometry
+ * @param {GLTF.Primitive} primitiveDef
+ * @param {GLTFParser} parser
+ * @return {Promise<BufferGeometry>}
+ */
+
+
+ function addPrimitiveAttributes( geometry, primitiveDef, parser ) {
+
+ const attributes = primitiveDef.attributes;
+ const pending = [];
+
+ function assignAttributeAccessor( accessorIndex, attributeName ) {
+
+ return parser.getDependency( 'accessor', accessorIndex ).then( function ( accessor ) {
+
+ geometry.setAttribute( attributeName, accessor );
+
+ } );
+
+ }
+
+ for ( const gltfAttributeName in attributes ) {
+
+ const threeAttributeName = ATTRIBUTES[ gltfAttributeName ] || gltfAttributeName.toLowerCase(); // Skip attributes already provided by e.g. Draco extension.
+
+ if ( threeAttributeName in geometry.attributes ) continue;
+ pending.push( assignAttributeAccessor( attributes[ gltfAttributeName ], threeAttributeName ) );
+
+ }
+
+ if ( primitiveDef.indices !== undefined && ! geometry.index ) {
+
+ const accessor = parser.getDependency( 'accessor', primitiveDef.indices ).then( function ( accessor ) {
+
+ geometry.setIndex( accessor );
+
+ } );
+ pending.push( accessor );
+
+ }
+
+ assignExtrasToUserData( geometry, primitiveDef );
+ computeBounds( geometry, primitiveDef, parser );
+ return Promise.all( pending ).then( function () {
+
+ return primitiveDef.targets !== undefined ? addMorphTargets( geometry, primitiveDef.targets, parser ) : geometry;
+
+ } );
+
+ }
+ /**
+ * @param {BufferGeometry} geometry
+ * @param {Number} drawMode
+ * @return {BufferGeometry}
+ */
+
+
+ function toTrianglesDrawMode( geometry, drawMode ) {
+
+ let index = geometry.getIndex(); // generate index if not present
+
+ if ( index === null ) {
+
+ const indices = [];
+ const position = geometry.getAttribute( 'position' );
+
+ if ( position !== undefined ) {
+
+ for ( let i = 0; i < position.count; i ++ ) {
+
+ indices.push( i );
+
+ }
+
+ geometry.setIndex( indices );
+ index = geometry.getIndex();
+
+ } else {
+
+ console.error( 'THREE.GLTFLoader.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.' );
+ return geometry;
+
+ }
+
+ } //
+
+
+ const numberOfTriangles = index.count - 2;
+ const newIndices = [];
+
+ if ( drawMode === THREE.TriangleFanDrawMode ) {
+
+ // gl.TRIANGLE_FAN
+ for ( let i = 1; i <= numberOfTriangles; i ++ ) {
+
+ newIndices.push( index.getX( 0 ) );
+ newIndices.push( index.getX( i ) );
+ newIndices.push( index.getX( i + 1 ) );
+
+ }
+
+ } else {
+
+ // gl.TRIANGLE_STRIP
+ for ( let i = 0; i < numberOfTriangles; i ++ ) {
+
+ if ( i % 2 === 0 ) {
+
+ newIndices.push( index.getX( i ) );
+ newIndices.push( index.getX( i + 1 ) );
+ newIndices.push( index.getX( i + 2 ) );
+
+ } else {
+
+ newIndices.push( index.getX( i + 2 ) );
+ newIndices.push( index.getX( i + 1 ) );
+ newIndices.push( index.getX( i ) );
+
+ }
+
+ }
+
+ }
+
+ if ( newIndices.length / 3 !== numberOfTriangles ) {
+
+ console.error( 'THREE.GLTFLoader.toTrianglesDrawMode(): Unable to generate correct amount of triangles.' );
+
+ } // build final geometry
+
+
+ const newGeometry = geometry.clone();
+ newGeometry.setIndex( newIndices );
+ return newGeometry;
+
+ }
+
+ THREE.GLTFLoader = GLTFLoader;
+
+} )();
diff --git a/downloads/LuminosityHighPassShader.js b/downloads/LuminosityHighPassShader.js
new file mode 100644
index 0000000..a5eab35
--- /dev/null
+++ b/downloads/LuminosityHighPassShader.js
@@ -0,0 +1,71 @@
+( function () {
+
+ /**
+ * Luminosity
+ * http://en.wikipedia.org/wiki/Luminosity
+ */
+
+ const LuminosityHighPassShader = {
+ shaderID: 'luminosityHighPass',
+ uniforms: {
+ 'tDiffuse': {
+ value: null
+ },
+ 'luminosityThreshold': {
+ value: 1.0
+ },
+ 'smoothWidth': {
+ value: 1.0
+ },
+ 'defaultColor': {
+ value: new THREE.Color( 0x000000 )
+ },
+ 'defaultOpacity': {
+ value: 0.0
+ }
+ },
+ vertexShader:
+ /* glsl */
+ `
+
+ varying vec2 vUv;
+
+ void main() {
+
+ vUv = uv;
+
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+
+ }`,
+ fragmentShader:
+ /* glsl */
+ `
+
+ uniform sampler2D tDiffuse;
+ uniform vec3 defaultColor;
+ uniform float defaultOpacity;
+ uniform float luminosityThreshold;
+ uniform float smoothWidth;
+
+ varying vec2 vUv;
+
+ void main() {
+
+ vec4 texel = texture2D( tDiffuse, vUv );
+
+ vec3 luma = vec3( 0.299, 0.587, 0.114 );
+
+ float v = dot( texel.xyz, luma );
+
+ vec4 outputColor = vec4( defaultColor.rgb, defaultOpacity );
+
+ float alpha = smoothstep( luminosityThreshold, luminosityThreshold + smoothWidth, v );
+
+ gl_FragColor = mix( outputColor, texel, alpha );
+
+ }`
+ };
+
+ THREE.LuminosityHighPassShader = LuminosityHighPassShader;
+
+} )();
diff --git a/downloads/RenderPass.js b/downloads/RenderPass.js
new file mode 100644
index 0000000..b212e77
--- /dev/null
+++ b/downloads/RenderPass.js
@@ -0,0 +1,74 @@
+( function () {
+
+ class RenderPass extends THREE.Pass {
+
+ constructor( scene, camera, overrideMaterial, clearColor, clearAlpha ) {
+
+ super();
+ this.scene = scene;
+ this.camera = camera;
+ this.overrideMaterial = overrideMaterial;
+ this.clearColor = clearColor;
+ this.clearAlpha = clearAlpha !== undefined ? clearAlpha : 0;
+ this.clear = true;
+ this.clearDepth = false;
+ this.needsSwap = false;
+ this._oldClearColor = new THREE.Color();
+
+ }
+
+ render( renderer, writeBuffer, readBuffer
+ /*, deltaTime, maskActive */
+ ) {
+
+ const oldAutoClear = renderer.autoClear;
+ renderer.autoClear = false;
+ let oldClearAlpha, oldOverrideMaterial;
+
+ if ( this.overrideMaterial !== undefined ) {
+
+ oldOverrideMaterial = this.scene.overrideMaterial;
+ this.scene.overrideMaterial = this.overrideMaterial;
+
+ }
+
+ if ( this.clearColor ) {
+
+ renderer.getClearColor( this._oldClearColor );
+ oldClearAlpha = renderer.getClearAlpha();
+ renderer.setClearColor( this.clearColor, this.clearAlpha );
+
+ }
+
+ if ( this.clearDepth ) {
+
+ renderer.clearDepth();
+
+ }
+
+ renderer.setRenderTarget( this.renderToScreen ? null : readBuffer ); // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
+
+ if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
+ renderer.render( this.scene, this.camera );
+
+ if ( this.clearColor ) {
+
+ renderer.setClearColor( this._oldClearColor, oldClearAlpha );
+
+ }
+
+ if ( this.overrideMaterial !== undefined ) {
+
+ this.scene.overrideMaterial = oldOverrideMaterial;
+
+ }
+
+ renderer.autoClear = oldAutoClear;
+
+ }
+
+ }
+
+ THREE.RenderPass = RenderPass;
+
+} )();
diff --git a/downloads/ShaderPass.js b/downloads/ShaderPass.js
new file mode 100644
index 0000000..9c508b3
--- /dev/null
+++ b/downloads/ShaderPass.js
@@ -0,0 +1,63 @@
+( function () {
+
+ class ShaderPass extends THREE.Pass {
+
+ constructor( shader, textureID ) {
+
+ super();
+ this.textureID = textureID !== undefined ? textureID : 'tDiffuse';
+
+ if ( shader instanceof THREE.ShaderMaterial ) {
+
+ this.uniforms = shader.uniforms;
+ this.material = shader;
+
+ } else if ( shader ) {
+
+ this.uniforms = THREE.UniformsUtils.clone( shader.uniforms );
+ this.material = new THREE.ShaderMaterial( {
+ defines: Object.assign( {}, shader.defines ),
+ uniforms: this.uniforms,
+ vertexShader: shader.vertexShader,
+ fragmentShader: shader.fragmentShader
+ } );
+
+ }
+
+ this.fsQuad = new THREE.FullScreenQuad( this.material );
+
+ }
+
+ render( renderer, writeBuffer, readBuffer
+ /*, deltaTime, maskActive */
+ ) {
+
+ if ( this.uniforms[ this.textureID ] ) {
+
+ this.uniforms[ this.textureID ].value = readBuffer.texture;
+
+ }
+
+ this.fsQuad.material = this.material;
+
+ if ( this.renderToScreen ) {
+
+ renderer.setRenderTarget( null );
+ this.fsQuad.render( renderer );
+
+ } else {
+
+ renderer.setRenderTarget( writeBuffer ); // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
+
+ if ( this.clear ) renderer.clear( renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil );
+ this.fsQuad.render( renderer );
+
+ }
+
+ }
+
+ }
+
+ THREE.ShaderPass = ShaderPass;
+
+} )();
diff --git a/downloads/TransformControls.js b/downloads/TransformControls.js
new file mode 100644
index 0000000..8422db8
--- /dev/null
+++ b/downloads/TransformControls.js
@@ -0,0 +1,1471 @@
+( function () {
+
+ const _raycaster = new THREE.Raycaster();
+
+ const _tempVector = new THREE.Vector3();
+
+ const _tempVector2 = new THREE.Vector3();
+
+ const _tempQuaternion = new THREE.Quaternion();
+
+ const _unit = {
+ X: new THREE.Vector3( 1, 0, 0 ),
+ Y: new THREE.Vector3( 0, 1, 0 ),
+ Z: new THREE.Vector3( 0, 0, 1 )
+ };
+ const _changeEvent = {
+ type: 'change'
+ };
+ const _mouseDownEvent = {
+ type: 'mouseDown'
+ };
+ const _mouseUpEvent = {
+ type: 'mouseUp',
+ mode: null
+ };
+ const _objectChangeEvent = {
+ type: 'objectChange'
+ };
+
+ class TransformControls extends THREE.Object3D {
+
+ constructor( camera, domElement ) {
+
+ super();
+
+ if ( domElement === undefined ) {
+
+ console.warn( 'THREE.TransformControls: The second parameter "domElement" is now mandatory.' );
+ domElement = document;
+
+ }
+
+ this.visible = false;
+ this.domElement = domElement;
+
+ const _gizmo = new TransformControlsGizmo();
+
+ this._gizmo = _gizmo;
+ this.add( _gizmo );
+
+ const _plane = new TransformControlsPlane();
+
+ this._plane = _plane;
+ this.add( _plane );
+ const scope = this; // Defined getter, setter and store for a property
+
+ function defineProperty( propName, defaultValue ) {
+
+ let propValue = defaultValue;
+ Object.defineProperty( scope, propName, {
+ get: function () {
+
+ return propValue !== undefined ? propValue : defaultValue;
+
+ },
+ set: function ( value ) {
+
+ if ( propValue !== value ) {
+
+ propValue = value;
+ _plane[ propName ] = value;
+ _gizmo[ propName ] = value;
+ scope.dispatchEvent( {
+ type: propName + '-changed',
+ value: value
+ } );
+ scope.dispatchEvent( _changeEvent );
+
+ }
+
+ }
+ } );
+ scope[ propName ] = defaultValue;
+ _plane[ propName ] = defaultValue;
+ _gizmo[ propName ] = defaultValue;
+
+ } // Define properties with getters/setter
+ // Setting the defined property will automatically trigger change event
+ // Defined properties are passed down to gizmo and plane
+
+
+ defineProperty( 'camera', camera );
+ defineProperty( 'object', undefined );
+ defineProperty( 'enabled', true );
+ defineProperty( 'axis', null );
+ defineProperty( 'mode', 'translate' );
+ defineProperty( 'translationSnap', null );
+ defineProperty( 'rotationSnap', null );
+ defineProperty( 'scaleSnap', null );
+ defineProperty( 'space', 'world' );
+ defineProperty( 'size', 1 );
+ defineProperty( 'dragging', false );
+ defineProperty( 'showX', true );
+ defineProperty( 'showY', true );
+ defineProperty( 'showZ', true ); // Reusable utility variables
+
+ const worldPosition = new THREE.Vector3();
+ const worldPositionStart = new THREE.Vector3();
+ const worldQuaternion = new THREE.Quaternion();
+ const worldQuaternionStart = new THREE.Quaternion();
+ const cameraPosition = new THREE.Vector3();
+ const cameraQuaternion = new THREE.Quaternion();
+ const pointStart = new THREE.Vector3();
+ const pointEnd = new THREE.Vector3();
+ const rotationAxis = new THREE.Vector3();
+ const rotationAngle = 0;
+ const eye = new THREE.Vector3(); // TODO: remove properties unused in plane and gizmo
+
+ defineProperty( 'worldPosition', worldPosition );
+ defineProperty( 'worldPositionStart', worldPositionStart );
+ defineProperty( 'worldQuaternion', worldQuaternion );
+ defineProperty( 'worldQuaternionStart', worldQuaternionStart );
+ defineProperty( 'cameraPosition', cameraPosition );
+ defineProperty( 'cameraQuaternion', cameraQuaternion );
+ defineProperty( 'pointStart', pointStart );
+ defineProperty( 'pointEnd', pointEnd );
+ defineProperty( 'rotationAxis', rotationAxis );
+ defineProperty( 'rotationAngle', rotationAngle );
+ defineProperty( 'eye', eye );
+ this._offset = new THREE.Vector3();
+ this._startNorm = new THREE.Vector3();
+ this._endNorm = new THREE.Vector3();
+ this._cameraScale = new THREE.Vector3();
+ this._parentPosition = new THREE.Vector3();
+ this._parentQuaternion = new THREE.Quaternion();
+ this._parentQuaternionInv = new THREE.Quaternion();
+ this._parentScale = new THREE.Vector3();
+ this._worldScaleStart = new THREE.Vector3();
+ this._worldQuaternionInv = new THREE.Quaternion();
+ this._worldScale = new THREE.Vector3();
+ this._positionStart = new THREE.Vector3();
+ this._quaternionStart = new THREE.Quaternion();
+ this._scaleStart = new THREE.Vector3();
+ this._getPointer = getPointer.bind( this );
+ this._onPointerDown = onPointerDown.bind( this );
+ this._onPointerHover = onPointerHover.bind( this );
+ this._onPointerMove = onPointerMove.bind( this );
+ this._onPointerUp = onPointerUp.bind( this );
+ this.domElement.addEventListener( 'pointerdown', this._onPointerDown );
+ this.domElement.addEventListener( 'pointermove', this._onPointerHover );
+ this.domElement.ownerDocument.addEventListener( 'pointerup', this._onPointerUp );
+
+ } // updateMatrixWorld updates key transformation variables
+
+
+ updateMatrixWorld() {
+
+ if ( this.object !== undefined ) {
+
+ this.object.updateMatrixWorld();
+
+ if ( this.object.parent === null ) {
+
+ console.error( 'TransformControls: The attached 3D object must be a part of the scene graph.' );
+
+ } else {
+
+ this.object.parent.matrixWorld.decompose( this._parentPosition, this._parentQuaternion, this._parentScale );
+
+ }
+
+ this.object.matrixWorld.decompose( this.worldPosition, this.worldQuaternion, this._worldScale );
+
+ this._parentQuaternionInv.copy( this._parentQuaternion ).invert();
+
+ this._worldQuaternionInv.copy( this.worldQuaternion ).invert();
+
+ }
+
+ this.camera.updateMatrixWorld();
+ this.camera.matrixWorld.decompose( this.cameraPosition, this.cameraQuaternion, this._cameraScale );
+ this.eye.copy( this.cameraPosition ).sub( this.worldPosition ).normalize();
+ super.updateMatrixWorld( this );
+
+ }
+
+ pointerHover( pointer ) {
+
+ if ( this.object === undefined || this.dragging === true ) return;
+
+ _raycaster.setFromCamera( pointer, this.camera );
+
+ const intersect = intersectObjectWithRay( this._gizmo.picker[ this.mode ], _raycaster );
+
+ if ( intersect ) {
+
+ this.axis = intersect.object.name;
+
+ } else {
+
+ this.axis = null;
+
+ }
+
+ }
+
+ pointerDown( pointer ) {
+
+ if ( this.object === undefined || this.dragging === true || pointer.button !== 0 ) return;
+
+ if ( this.axis !== null ) {
+
+ _raycaster.setFromCamera( pointer, this.camera );
+
+ const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );
+
+ if ( planeIntersect ) {
+
+ let space = this.space;
+
+ if ( this.mode === 'scale' ) {
+
+ space = 'local';
+
+ } else if ( this.axis === 'E' || this.axis === 'XYZE' || this.axis === 'XYZ' ) {
+
+ space = 'world';
+
+ }
+
+ if ( space === 'local' && this.mode === 'rotate' ) {
+
+ const snap = this.rotationSnap;
+ if ( this.axis === 'X' && snap ) this.object.rotation.x = Math.round( this.object.rotation.x / snap ) * snap;
+ if ( this.axis === 'Y' && snap ) this.object.rotation.y = Math.round( this.object.rotation.y / snap ) * snap;
+ if ( this.axis === 'Z' && snap ) this.object.rotation.z = Math.round( this.object.rotation.z / snap ) * snap;
+
+ }
+
+ this.object.updateMatrixWorld();
+ this.object.parent.updateMatrixWorld();
+
+ this._positionStart.copy( this.object.position );
+
+ this._quaternionStart.copy( this.object.quaternion );
+
+ this._scaleStart.copy( this.object.scale );
+
+ this.object.matrixWorld.decompose( this.worldPositionStart, this.worldQuaternionStart, this._worldScaleStart );
+ this.pointStart.copy( planeIntersect.point ).sub( this.worldPositionStart );
+
+ }
+
+ this.dragging = true;
+ _mouseDownEvent.mode = this.mode;
+ this.dispatchEvent( _mouseDownEvent );
+
+ }
+
+ }
+
+ pointerMove( pointer ) {
+
+ const axis = this.axis;
+ const mode = this.mode;
+ const object = this.object;
+ let space = this.space;
+
+ if ( mode === 'scale' ) {
+
+ space = 'local';
+
+ } else if ( axis === 'E' || axis === 'XYZE' || axis === 'XYZ' ) {
+
+ space = 'world';
+
+ }
+
+ if ( object === undefined || axis === null || this.dragging === false || pointer.button !== - 1 ) return;
+
+ _raycaster.setFromCamera( pointer, this.camera );
+
+ const planeIntersect = intersectObjectWithRay( this._plane, _raycaster, true );
+ if ( ! planeIntersect ) return;
+ this.pointEnd.copy( planeIntersect.point ).sub( this.worldPositionStart );
+
+ if ( mode === 'translate' ) {
+
+ // Apply translate
+ this._offset.copy( this.pointEnd ).sub( this.pointStart );
+
+ if ( space === 'local' && axis !== 'XYZ' ) {
+
+ this._offset.applyQuaternion( this._worldQuaternionInv );
+
+ }
+
+ if ( axis.indexOf( 'X' ) === - 1 ) this._offset.x = 0;
+ if ( axis.indexOf( 'Y' ) === - 1 ) this._offset.y = 0;
+ if ( axis.indexOf( 'Z' ) === - 1 ) this._offset.z = 0;
+
+ if ( space === 'local' && axis !== 'XYZ' ) {
+
+ this._offset.applyQuaternion( this._quaternionStart ).divide( this._parentScale );
+
+ } else {
+
+ this._offset.applyQuaternion( this._parentQuaternionInv ).divide( this._parentScale );
+
+ }
+
+ object.position.copy( this._offset ).add( this._positionStart ); // Apply translation snap
+
+ if ( this.translationSnap ) {
+
+ if ( space === 'local' ) {
+
+ object.position.applyQuaternion( _tempQuaternion.copy( this._quaternionStart ).invert() );
+
+ if ( axis.search( 'X' ) !== - 1 ) {
+
+ object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;
+
+ }
+
+ if ( axis.search( 'Y' ) !== - 1 ) {
+
+ object.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;
+
+ }
+
+ if ( axis.search( 'Z' ) !== - 1 ) {
+
+ object.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;
+
+ }
+
+ object.position.applyQuaternion( this._quaternionStart );
+
+ }
+
+ if ( space === 'world' ) {
+
+ if ( object.parent ) {
+
+ object.position.add( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) );
+
+ }
+
+ if ( axis.search( 'X' ) !== - 1 ) {
+
+ object.position.x = Math.round( object.position.x / this.translationSnap ) * this.translationSnap;
+
+ }
+
+ if ( axis.search( 'Y' ) !== - 1 ) {
+
+ object.position.y = Math.round( object.position.y / this.translationSnap ) * this.translationSnap;
+
+ }
+
+ if ( axis.search( 'Z' ) !== - 1 ) {
+
+ object.position.z = Math.round( object.position.z / this.translationSnap ) * this.translationSnap;
+
+ }
+
+ if ( object.parent ) {
+
+ object.position.sub( _tempVector.setFromMatrixPosition( object.parent.matrixWorld ) );
+
+ }
+
+ }
+
+ }
+
+ } else if ( mode === 'scale' ) {
+
+ if ( axis.search( 'XYZ' ) !== - 1 ) {
+
+ let d = this.pointEnd.length() / this.pointStart.length();
+ if ( this.pointEnd.dot( this.pointStart ) < 0 ) d *= - 1;
+
+ _tempVector2.set( d, d, d );
+
+ } else {
+
+ _tempVector.copy( this.pointStart );
+
+ _tempVector2.copy( this.pointEnd );
+
+ _tempVector.applyQuaternion( this._worldQuaternionInv );
+
+ _tempVector2.applyQuaternion( this._worldQuaternionInv );
+
+ _tempVector2.divide( _tempVector );
+
+ if ( axis.search( 'X' ) === - 1 ) {
+
+ _tempVector2.x = 1;
+
+ }
+
+ if ( axis.search( 'Y' ) === - 1 ) {
+
+ _tempVector2.y = 1;
+
+ }
+
+ if ( axis.search( 'Z' ) === - 1 ) {
+
+ _tempVector2.z = 1;
+
+ }
+
+ } // Apply scale
+
+
+ object.scale.copy( this._scaleStart ).multiply( _tempVector2 );
+
+ if ( this.scaleSnap ) {
+
+ if ( axis.search( 'X' ) !== - 1 ) {
+
+ object.scale.x = Math.round( object.scale.x / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;
+
+ }
+
+ if ( axis.search( 'Y' ) !== - 1 ) {
+
+ object.scale.y = Math.round( object.scale.y / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;
+
+ }
+
+ if ( axis.search( 'Z' ) !== - 1 ) {
+
+ object.scale.z = Math.round( object.scale.z / this.scaleSnap ) * this.scaleSnap || this.scaleSnap;
+
+ }
+
+ }
+
+ } else if ( mode === 'rotate' ) {
+
+ this._offset.copy( this.pointEnd ).sub( this.pointStart );
+
+ const ROTATION_SPEED = 20 / this.worldPosition.distanceTo( _tempVector.setFromMatrixPosition( this.camera.matrixWorld ) );
+
+ if ( axis === 'E' ) {
+
+ this.rotationAxis.copy( this.eye );
+ this.rotationAngle = this.pointEnd.angleTo( this.pointStart );
+
+ this._startNorm.copy( this.pointStart ).normalize();
+
+ this._endNorm.copy( this.pointEnd ).normalize();
+
+ this.rotationAngle *= this._endNorm.cross( this._startNorm ).dot( this.eye ) < 0 ? 1 : - 1;
+
+ } else if ( axis === 'XYZE' ) {
+
+ this.rotationAxis.copy( this._offset ).cross( this.eye ).normalize();
+ this.rotationAngle = this._offset.dot( _tempVector.copy( this.rotationAxis ).cross( this.eye ) ) * ROTATION_SPEED;
+
+ } else if ( axis === 'X' || axis === 'Y' || axis === 'Z' ) {
+
+ this.rotationAxis.copy( _unit[ axis ] );
+
+ _tempVector.copy( _unit[ axis ] );
+
+ if ( space === 'local' ) {
+
+ _tempVector.applyQuaternion( this.worldQuaternion );
+
+ }
+
+ this.rotationAngle = this._offset.dot( _tempVector.cross( this.eye ).normalize() ) * ROTATION_SPEED;
+
+ } // Apply rotation snap
+
+
+ if ( this.rotationSnap ) this.rotationAngle = Math.round( this.rotationAngle / this.rotationSnap ) * this.rotationSnap; // Apply rotate
+
+ if ( space === 'local' && axis !== 'E' && axis !== 'XYZE' ) {
+
+ object.quaternion.copy( this._quaternionStart );
+ object.quaternion.multiply( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) ).normalize();
+
+ } else {
+
+ this.rotationAxis.applyQuaternion( this._parentQuaternionInv );
+ object.quaternion.copy( _tempQuaternion.setFromAxisAngle( this.rotationAxis, this.rotationAngle ) );
+ object.quaternion.multiply( this._quaternionStart ).normalize();
+
+ }
+
+ }
+
+ this.dispatchEvent( _changeEvent );
+ this.dispatchEvent( _objectChangeEvent );
+
+ }
+
+ pointerUp( pointer ) {
+
+ if ( pointer.button !== 0 ) return;
+
+ if ( this.dragging && this.axis !== null ) {
+
+ _mouseUpEvent.mode = this.mode;
+ this.dispatchEvent( _mouseUpEvent );
+
+ }
+
+ this.dragging = false;
+ this.axis = null;
+
+ }
+
+ dispose() {
+
+ this.domElement.removeEventListener( 'pointerdown', this._onPointerDown );
+ this.domElement.removeEventListener( 'pointermove', this._onPointerHover );
+ this.domElement.ownerDocument.removeEventListener( 'pointermove', this._onPointerMove );
+ this.domElement.ownerDocument.removeEventListener( 'pointerup', this._onPointerUp );
+ this.traverse( function ( child ) {
+
+ if ( child.geometry ) child.geometry.dispose();
+ if ( child.material ) child.material.dispose();
+
+ } );
+
+ } // Set current object
+
+
+ attach( object ) {
+
+ this.object = object;
+ this.visible = true;
+ return this;
+
+ } // Detatch from object
+
+
+ detach() {
+
+ this.object = undefined;
+ this.visible = false;
+ this.axis = null;
+ return this;
+
+ } // TODO: deprecate
+
+
+ getMode() {
+
+ return this.mode;
+
+ }
+
+ setMode( mode ) {
+
+ this.mode = mode;
+
+ }
+
+ setTranslationSnap( translationSnap ) {
+
+ this.translationSnap = translationSnap;
+
+ }
+
+ setRotationSnap( rotationSnap ) {
+
+ this.rotationSnap = rotationSnap;
+
+ }
+
+ setScaleSnap( scaleSnap ) {
+
+ this.scaleSnap = scaleSnap;
+
+ }
+
+ setSize( size ) {
+
+ this.size = size;
+
+ }
+
+ setSpace( space ) {
+
+ this.space = space;
+
+ }
+
+ update() {
+
+ console.warn( 'THREE.TransformControls: update function has no more functionality and therefore has been deprecated.' );
+
+ }
+
+ }
+
+ TransformControls.prototype.isTransformControls = true; // mouse / touch event handlers
+
+ function getPointer( event ) {
+
+ if ( this.domElement.ownerDocument.pointerLockElement ) {
+
+ return {
+ x: 0,
+ y: 0,
+ button: event.button
+ };
+
+ } else {
+
+ const pointer = event.changedTouches ? event.changedTouches[ 0 ] : event;
+ const rect = this.domElement.getBoundingClientRect();
+ return {
+ x: ( pointer.clientX - rect.left ) / rect.width * 2 - 1,
+ y: - ( pointer.clientY - rect.top ) / rect.height * 2 + 1,
+ button: event.button
+ };
+
+ }
+
+ }
+
+ function onPointerHover( event ) {
+
+ if ( ! this.enabled ) return;
+
+ switch ( event.pointerType ) {
+
+ case 'mouse':
+ case 'pen':
+ this.pointerHover( this._getPointer( event ) );
+ break;
+
+ }
+
+ }
+
+ function onPointerDown( event ) {
+
+ if ( ! this.enabled ) return;
+ this.domElement.style.touchAction = 'none'; // disable touch scroll
+
+ this.domElement.ownerDocument.addEventListener( 'pointermove', this._onPointerMove );
+ this.pointerHover( this._getPointer( event ) );
+ this.pointerDown( this._getPointer( event ) );
+
+ }
+
+ function onPointerMove( event ) {
+
+ if ( ! this.enabled ) return;
+ this.pointerMove( this._getPointer( event ) );
+
+ }
+
+ function onPointerUp( event ) {
+
+ if ( ! this.enabled ) return;
+ this.domElement.style.touchAction = '';
+ this.domElement.ownerDocument.removeEventListener( 'pointermove', this._onPointerMove );
+ this.pointerUp( this._getPointer( event ) );
+
+ }
+
+ function intersectObjectWithRay( object, raycaster, includeInvisible ) {
+
+ const allIntersections = raycaster.intersectObject( object, true );
+
+ for ( let i = 0; i < allIntersections.length; i ++ ) {
+
+ if ( allIntersections[ i ].object.visible || includeInvisible ) {
+
+ return allIntersections[ i ];
+
+ }
+
+ }
+
+ return false;
+
+ } //
+ // Reusable utility variables
+
+
+ const _tempEuler = new THREE.Euler();
+
+ const _alignVector = new THREE.Vector3( 0, 1, 0 );
+
+ const _zeroVector = new THREE.Vector3( 0, 0, 0 );
+
+ const _lookAtMatrix = new THREE.Matrix4();
+
+ const _tempQuaternion2 = new THREE.Quaternion();
+
+ const _identityQuaternion = new THREE.Quaternion();
+
+ const _dirVector = new THREE.Vector3();
+
+ const _tempMatrix = new THREE.Matrix4();
+
+ const _unitX = new THREE.Vector3( 1, 0, 0 );
+
+ const _unitY = new THREE.Vector3( 0, 1, 0 );
+
+ const _unitZ = new THREE.Vector3( 0, 0, 1 );
+
+ const _v1 = new THREE.Vector3();
+
+ const _v2 = new THREE.Vector3();
+
+ const _v3 = new THREE.Vector3();
+
+ class TransformControlsGizmo extends THREE.Object3D {
+
+ constructor() {
+
+ super();
+ this.type = 'TransformControlsGizmo'; // shared materials
+
+ const gizmoMaterial = new THREE.MeshBasicMaterial( {
+ depthTest: false,
+ depthWrite: false,
+ transparent: true,
+ side: THREE.DoubleSide,
+ fog: false,
+ toneMapped: false
+ } );
+ const gizmoLineMaterial = new THREE.LineBasicMaterial( {
+ depthTest: false,
+ depthWrite: false,
+ transparent: true,
+ linewidth: 1,
+ fog: false,
+ toneMapped: false
+ } ); // Make unique material for each axis/color
+
+ const matInvisible = gizmoMaterial.clone();
+ matInvisible.opacity = 0.15;
+ const matHelper = gizmoMaterial.clone();
+ matHelper.opacity = 0.33;
+ const matRed = gizmoMaterial.clone();
+ matRed.color.set( 0xff0000 );
+ const matGreen = gizmoMaterial.clone();
+ matGreen.color.set( 0x00ff00 );
+ const matBlue = gizmoMaterial.clone();
+ matBlue.color.set( 0x0000ff );
+ const matWhiteTransparent = gizmoMaterial.clone();
+ matWhiteTransparent.opacity = 0.25;
+ const matYellowTransparent = matWhiteTransparent.clone();
+ matYellowTransparent.color.set( 0xffff00 );
+ const matCyanTransparent = matWhiteTransparent.clone();
+ matCyanTransparent.color.set( 0x00ffff );
+ const matMagentaTransparent = matWhiteTransparent.clone();
+ matMagentaTransparent.color.set( 0xff00ff );
+ const matYellow = gizmoMaterial.clone();
+ matYellow.color.set( 0xffff00 );
+ const matLineRed = gizmoLineMaterial.clone();
+ matLineRed.color.set( 0xff0000 );
+ const matLineGreen = gizmoLineMaterial.clone();
+ matLineGreen.color.set( 0x00ff00 );
+ const matLineBlue = gizmoLineMaterial.clone();
+ matLineBlue.color.set( 0x0000ff );
+ const matLineCyan = gizmoLineMaterial.clone();
+ matLineCyan.color.set( 0x00ffff );
+ const matLineMagenta = gizmoLineMaterial.clone();
+ matLineMagenta.color.set( 0xff00ff );
+ const matLineYellow = gizmoLineMaterial.clone();
+ matLineYellow.color.set( 0xffff00 );
+ const matLineGray = gizmoLineMaterial.clone();
+ matLineGray.color.set( 0x787878 );
+ const matLineYellowTransparent = matLineYellow.clone();
+ matLineYellowTransparent.opacity = 0.25; // reusable geometry
+
+ const arrowGeometry = new THREE.CylinderGeometry( 0, 0.05, 0.2, 12, 1, false );
+ const scaleHandleGeometry = new THREE.BoxGeometry( 0.125, 0.125, 0.125 );
+ const lineGeometry = new THREE.BufferGeometry();
+ lineGeometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 0, 0 ], 3 ) );
+
+ function CircleGeometry( radius, arc ) {
+
+ const geometry = new THREE.BufferGeometry();
+ const vertices = [];
+
+ for ( let i = 0; i <= 64 * arc; ++ i ) {
+
+ vertices.push( 0, Math.cos( i / 32 * Math.PI ) * radius, Math.sin( i / 32 * Math.PI ) * radius );
+
+ }
+
+ geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( vertices, 3 ) );
+ return geometry;
+
+ } // Special geometry for transform helper. If scaled with position vector it spans from [0,0,0] to position
+
+
+ function TranslateHelperGeometry() {
+
+ const geometry = new THREE.BufferGeometry();
+ geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( [ 0, 0, 0, 1, 1, 1 ], 3 ) );
+ return geometry;
+
+ } // Gizmo definitions - custom hierarchy definitions for setupGizmo() function
+
+
+ const gizmoTranslate = {
+ X: [[ new THREE.Mesh( arrowGeometry, matRed ), [ 1, 0, 0 ], [ 0, 0, - Math.PI / 2 ], null, 'fwd' ], [ new THREE.Mesh( arrowGeometry, matRed ), [ 1, 0, 0 ], [ 0, 0, Math.PI / 2 ], null, 'bwd' ], [ new THREE.Line( lineGeometry, matLineRed ) ]],
+ Y: [[ new THREE.Mesh( arrowGeometry, matGreen ), [ 0, 1, 0 ], null, null, 'fwd' ], [ new THREE.Mesh( arrowGeometry, matGreen ), [ 0, 1, 0 ], [ Math.PI, 0, 0 ], null, 'bwd' ], [ new THREE.Line( lineGeometry, matLineGreen ), null, [ 0, 0, Math.PI / 2 ]]],
+ Z: [[ new THREE.Mesh( arrowGeometry, matBlue ), [ 0, 0, 1 ], [ Math.PI / 2, 0, 0 ], null, 'fwd' ], [ new THREE.Mesh( arrowGeometry, matBlue ), [ 0, 0, 1 ], [ - Math.PI / 2, 0, 0 ], null, 'bwd' ], [ new THREE.Line( lineGeometry, matLineBlue ), null, [ 0, - Math.PI / 2, 0 ]]],
+ XYZ: [[ new THREE.Mesh( new THREE.OctahedronGeometry( 0.1, 0 ), matWhiteTransparent.clone() ), [ 0, 0, 0 ], [ 0, 0, 0 ]]],
+ XY: [[ new THREE.Mesh( new THREE.PlaneGeometry( 0.295, 0.295 ), matYellowTransparent.clone() ), [ 0.15, 0.15, 0 ]], [ new THREE.Line( lineGeometry, matLineYellow ), [ 0.18, 0.3, 0 ], null, [ 0.125, 1, 1 ]], [ new THREE.Line( lineGeometry, matLineYellow ), [ 0.3, 0.18, 0 ], [ 0, 0, Math.PI / 2 ], [ 0.125, 1, 1 ]]],
+ YZ: [[ new THREE.Mesh( new THREE.PlaneGeometry( 0.295, 0.295 ), matCyanTransparent.clone() ), [ 0, 0.15, 0.15 ], [ 0, Math.PI / 2, 0 ]], [ new THREE.Line( lineGeometry, matLineCyan ), [ 0, 0.18, 0.3 ], [ 0, 0, Math.PI / 2 ], [ 0.125, 1, 1 ]], [ new THREE.Line( lineGeometry, matLineCyan ), [ 0, 0.3, 0.18 ], [ 0, - Math.PI / 2, 0 ], [ 0.125, 1, 1 ]]],
+ XZ: [[ new THREE.Mesh( new THREE.PlaneGeometry( 0.295, 0.295 ), matMagentaTransparent.clone() ), [ 0.15, 0, 0.15 ], [ - Math.PI / 2, 0, 0 ]], [ new THREE.Line( lineGeometry, matLineMagenta ), [ 0.18, 0, 0.3 ], null, [ 0.125, 1, 1 ]], [ new THREE.Line( lineGeometry, matLineMagenta ), [ 0.3, 0, 0.18 ], [ 0, - Math.PI / 2, 0 ], [ 0.125, 1, 1 ]]]
+ };
+ const pickerTranslate = {
+ X: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), matInvisible ), [ 0.6, 0, 0 ], [ 0, 0, - Math.PI / 2 ]]],
+ Y: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), matInvisible ), [ 0, 0.6, 0 ]]],
+ Z: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 1, 4, 1, false ), matInvisible ), [ 0, 0, 0.6 ], [ Math.PI / 2, 0, 0 ]]],
+ XYZ: [[ new THREE.Mesh( new THREE.OctahedronGeometry( 0.2, 0 ), matInvisible ) ]],
+ XY: [[ new THREE.Mesh( new THREE.PlaneGeometry( 0.4, 0.4 ), matInvisible ), [ 0.2, 0.2, 0 ]]],
+ YZ: [[ new THREE.Mesh( new THREE.PlaneGeometry( 0.4, 0.4 ), matInvisible ), [ 0, 0.2, 0.2 ], [ 0, Math.PI / 2, 0 ]]],
+ XZ: [[ new THREE.Mesh( new THREE.PlaneGeometry( 0.4, 0.4 ), matInvisible ), [ 0.2, 0, 0.2 ], [ - Math.PI / 2, 0, 0 ]]]
+ };
+ const helperTranslate = {
+ START: [[ new THREE.Mesh( new THREE.OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]],
+ END: [[ new THREE.Mesh( new THREE.OctahedronGeometry( 0.01, 2 ), matHelper ), null, null, null, 'helper' ]],
+ DELTA: [[ new THREE.Line( TranslateHelperGeometry(), matHelper ), null, null, null, 'helper' ]],
+ X: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]],
+ Y: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]],
+ Z: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]]
+ };
+ const gizmoRotate = {
+ X: [[ new THREE.Line( CircleGeometry( 1, 0.5 ), matLineRed ) ], [ new THREE.Mesh( new THREE.OctahedronGeometry( 0.04, 0 ), matRed ), [ 0, 0, 0.99 ], null, [ 1, 3, 1 ]]],
+ Y: [[ new THREE.Line( CircleGeometry( 1, 0.5 ), matLineGreen ), null, [ 0, 0, - Math.PI / 2 ]], [ new THREE.Mesh( new THREE.OctahedronGeometry( 0.04, 0 ), matGreen ), [ 0, 0, 0.99 ], null, [ 3, 1, 1 ]]],
+ Z: [[ new THREE.Line( CircleGeometry( 1, 0.5 ), matLineBlue ), null, [ 0, Math.PI / 2, 0 ]], [ new THREE.Mesh( new THREE.OctahedronGeometry( 0.04, 0 ), matBlue ), [ 0.99, 0, 0 ], null, [ 1, 3, 1 ]]],
+ E: [[ new THREE.Line( CircleGeometry( 1.25, 1 ), matLineYellowTransparent ), null, [ 0, Math.PI / 2, 0 ]], [ new THREE.Mesh( new THREE.CylinderGeometry( 0.03, 0, 0.15, 4, 1, false ), matLineYellowTransparent ), [ 1.17, 0, 0 ], [ 0, 0, - Math.PI / 2 ], [ 1, 1, 0.001 ]], [ new THREE.Mesh( new THREE.CylinderGeometry( 0.03, 0, 0.15, 4, 1, false ), matLineYellowTransparent ), [ - 1.17, 0, 0 ], [ 0, 0, Math.PI / 2 ], [ 1, 1, 0.001 ]], [ new THREE.Mesh( new THREE.CylinderGeometry( 0.03, 0, 0.15, 4, 1, false ), matLineYellowTransparent ), [ 0, - 1.17, 0 ], [ Math.PI, 0, 0 ], [ 1, 1, 0.001 ]], [ new THREE.Mesh( new THREE.CylinderGeometry( 0.03, 0, 0.15, 4, 1, false ), matLineYellowTransparent ), [ 0, 1.17, 0 ], [ 0, 0, 0 ], [ 1, 1, 0.001 ]]],
+ XYZE: [[ new THREE.Line( CircleGeometry( 1, 1 ), matLineGray ), null, [ 0, Math.PI / 2, 0 ]]]
+ };
+ const helperRotate = {
+ AXIS: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]]
+ };
+ const pickerRotate = {
+ X: [[ new THREE.Mesh( new THREE.TorusGeometry( 1, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, - Math.PI / 2, - Math.PI / 2 ]]],
+ Y: [[ new THREE.Mesh( new THREE.TorusGeometry( 1, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ Math.PI / 2, 0, 0 ]]],
+ Z: [[ new THREE.Mesh( new THREE.TorusGeometry( 1, 0.1, 4, 24 ), matInvisible ), [ 0, 0, 0 ], [ 0, 0, - Math.PI / 2 ]]],
+ E: [[ new THREE.Mesh( new THREE.TorusGeometry( 1.25, 0.1, 2, 24 ), matInvisible ) ]],
+ XYZE: [[ new THREE.Mesh( new THREE.SphereGeometry( 0.7, 10, 8 ), matInvisible ) ]]
+ };
+ const gizmoScale = {
+ X: [[ new THREE.Mesh( scaleHandleGeometry, matRed ), [ 0.8, 0, 0 ], [ 0, 0, - Math.PI / 2 ]], [ new THREE.Line( lineGeometry, matLineRed ), null, null, [ 0.8, 1, 1 ]]],
+ Y: [[ new THREE.Mesh( scaleHandleGeometry, matGreen ), [ 0, 0.8, 0 ]], [ new THREE.Line( lineGeometry, matLineGreen ), null, [ 0, 0, Math.PI / 2 ], [ 0.8, 1, 1 ]]],
+ Z: [[ new THREE.Mesh( scaleHandleGeometry, matBlue ), [ 0, 0, 0.8 ], [ Math.PI / 2, 0, 0 ]], [ new THREE.Line( lineGeometry, matLineBlue ), null, [ 0, - Math.PI / 2, 0 ], [ 0.8, 1, 1 ]]],
+ XY: [[ new THREE.Mesh( scaleHandleGeometry, matYellowTransparent ), [ 0.85, 0.85, 0 ], null, [ 2, 2, 0.2 ]], [ new THREE.Line( lineGeometry, matLineYellow ), [ 0.855, 0.98, 0 ], null, [ 0.125, 1, 1 ]], [ new THREE.Line( lineGeometry, matLineYellow ), [ 0.98, 0.855, 0 ], [ 0, 0, Math.PI / 2 ], [ 0.125, 1, 1 ]]],
+ YZ: [[ new THREE.Mesh( scaleHandleGeometry, matCyanTransparent ), [ 0, 0.85, 0.85 ], null, [ 0.2, 2, 2 ]], [ new THREE.Line( lineGeometry, matLineCyan ), [ 0, 0.855, 0.98 ], [ 0, 0, Math.PI / 2 ], [ 0.125, 1, 1 ]], [ new THREE.Line( lineGeometry, matLineCyan ), [ 0, 0.98, 0.855 ], [ 0, - Math.PI / 2, 0 ], [ 0.125, 1, 1 ]]],
+ XZ: [[ new THREE.Mesh( scaleHandleGeometry, matMagentaTransparent ), [ 0.85, 0, 0.85 ], null, [ 2, 0.2, 2 ]], [ new THREE.Line( lineGeometry, matLineMagenta ), [ 0.855, 0, 0.98 ], null, [ 0.125, 1, 1 ]], [ new THREE.Line( lineGeometry, matLineMagenta ), [ 0.98, 0, 0.855 ], [ 0, - Math.PI / 2, 0 ], [ 0.125, 1, 1 ]]],
+ XYZX: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.125, 0.125, 0.125 ), matWhiteTransparent.clone() ), [ 1.1, 0, 0 ]]],
+ XYZY: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.125, 0.125, 0.125 ), matWhiteTransparent.clone() ), [ 0, 1.1, 0 ]]],
+ XYZZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.125, 0.125, 0.125 ), matWhiteTransparent.clone() ), [ 0, 0, 1.1 ]]]
+ };
+ const pickerScale = {
+ X: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.8, 4, 1, false ), matInvisible ), [ 0.5, 0, 0 ], [ 0, 0, - Math.PI / 2 ]]],
+ Y: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.8, 4, 1, false ), matInvisible ), [ 0, 0.5, 0 ]]],
+ Z: [[ new THREE.Mesh( new THREE.CylinderGeometry( 0.2, 0, 0.8, 4, 1, false ), matInvisible ), [ 0, 0, 0.5 ], [ Math.PI / 2, 0, 0 ]]],
+ XY: [[ new THREE.Mesh( scaleHandleGeometry, matInvisible ), [ 0.85, 0.85, 0 ], null, [ 3, 3, 0.2 ]]],
+ YZ: [[ new THREE.Mesh( scaleHandleGeometry, matInvisible ), [ 0, 0.85, 0.85 ], null, [ 0.2, 3, 3 ]]],
+ XZ: [[ new THREE.Mesh( scaleHandleGeometry, matInvisible ), [ 0.85, 0, 0.85 ], null, [ 3, 0.2, 3 ]]],
+ XYZX: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.2, 0.2, 0.2 ), matInvisible ), [ 1.1, 0, 0 ]]],
+ XYZY: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.2, 0.2, 0.2 ), matInvisible ), [ 0, 1.1, 0 ]]],
+ XYZZ: [[ new THREE.Mesh( new THREE.BoxGeometry( 0.2, 0.2, 0.2 ), matInvisible ), [ 0, 0, 1.1 ]]]
+ };
+ const helperScale = {
+ X: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ - 1e3, 0, 0 ], null, [ 1e6, 1, 1 ], 'helper' ]],
+ Y: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ 0, - 1e3, 0 ], [ 0, 0, Math.PI / 2 ], [ 1e6, 1, 1 ], 'helper' ]],
+ Z: [[ new THREE.Line( lineGeometry, matHelper.clone() ), [ 0, 0, - 1e3 ], [ 0, - Math.PI / 2, 0 ], [ 1e6, 1, 1 ], 'helper' ]]
+ }; // Creates an THREE.Object3D with gizmos described in custom hierarchy definition.
+
+ function setupGizmo( gizmoMap ) {
+
+ const gizmo = new THREE.Object3D();
+
+ for ( const name in gizmoMap ) {
+
+ for ( let i = gizmoMap[ name ].length; i --; ) {
+
+ const object = gizmoMap[ name ][ i ][ 0 ].clone();
+ const position = gizmoMap[ name ][ i ][ 1 ];
+ const rotation = gizmoMap[ name ][ i ][ 2 ];
+ const scale = gizmoMap[ name ][ i ][ 3 ];
+ const tag = gizmoMap[ name ][ i ][ 4 ]; // name and tag properties are essential for picking and updating logic.
+
+ object.name = name;
+ object.tag = tag;
+
+ if ( position ) {
+
+ object.position.set( position[ 0 ], position[ 1 ], position[ 2 ] );
+
+ }
+
+ if ( rotation ) {
+
+ object.rotation.set( rotation[ 0 ], rotation[ 1 ], rotation[ 2 ] );
+
+ }
+
+ if ( scale ) {
+
+ object.scale.set( scale[ 0 ], scale[ 1 ], scale[ 2 ] );
+
+ }
+
+ object.updateMatrix();
+ const tempGeometry = object.geometry.clone();
+ tempGeometry.applyMatrix4( object.matrix );
+ object.geometry = tempGeometry;
+ object.renderOrder = Infinity;
+ object.position.set( 0, 0, 0 );
+ object.rotation.set( 0, 0, 0 );
+ object.scale.set( 1, 1, 1 );
+ gizmo.add( object );
+
+ }
+
+ }
+
+ return gizmo;
+
+ } // Gizmo creation
+
+
+ this.gizmo = {};
+ this.picker = {};
+ this.helper = {};
+ this.add( this.gizmo[ 'translate' ] = setupGizmo( gizmoTranslate ) );
+ this.add( this.gizmo[ 'rotate' ] = setupGizmo( gizmoRotate ) );
+ this.add( this.gizmo[ 'scale' ] = setupGizmo( gizmoScale ) );
+ this.add( this.picker[ 'translate' ] = setupGizmo( pickerTranslate ) );
+ this.add( this.picker[ 'rotate' ] = setupGizmo( pickerRotate ) );
+ this.add( this.picker[ 'scale' ] = setupGizmo( pickerScale ) );
+ this.add( this.helper[ 'translate' ] = setupGizmo( helperTranslate ) );
+ this.add( this.helper[ 'rotate' ] = setupGizmo( helperRotate ) );
+ this.add( this.helper[ 'scale' ] = setupGizmo( helperScale ) ); // Pickers should be hidden always
+
+ this.picker[ 'translate' ].visible = false;
+ this.picker[ 'rotate' ].visible = false;
+ this.picker[ 'scale' ].visible = false;
+
+ } // updateMatrixWorld will update transformations and appearance of individual handles
+
+
+ updateMatrixWorld( force ) {
+
+ const space = this.mode === 'scale' ? this.space : 'local'; // scale always oriented to local rotation
+
+ const quaternion = space === 'local' ? this.worldQuaternion : _identityQuaternion; // Show only gizmos for current transform mode
+
+ this.gizmo[ 'translate' ].visible = this.mode === 'translate';
+ this.gizmo[ 'rotate' ].visible = this.mode === 'rotate';
+ this.gizmo[ 'scale' ].visible = this.mode === 'scale';
+ this.helper[ 'translate' ].visible = this.mode === 'translate';
+ this.helper[ 'rotate' ].visible = this.mode === 'rotate';
+ this.helper[ 'scale' ].visible = this.mode === 'scale';
+ let handles = [];
+ handles = handles.concat( this.picker[ this.mode ].children );
+ handles = handles.concat( this.gizmo[ this.mode ].children );
+ handles = handles.concat( this.helper[ this.mode ].children );
+
+ for ( let i = 0; i < handles.length; i ++ ) {
+
+ const handle = handles[ i ]; // hide aligned to camera
+
+ handle.visible = true;
+ handle.rotation.set( 0, 0, 0 );
+ handle.position.copy( this.worldPosition );
+ let factor;
+
+ if ( this.camera.isOrthographicCamera ) {
+
+ factor = ( this.camera.top - this.camera.bottom ) / this.camera.zoom;
+
+ } else {
+
+ factor = this.worldPosition.distanceTo( this.cameraPosition ) * Math.min( 1.9 * Math.tan( Math.PI * this.camera.fov / 360 ) / this.camera.zoom, 7 );
+
+ }
+
+ handle.scale.set( 1, 1, 1 ).multiplyScalar( factor * this.size / 7 ); // TODO: simplify helpers and consider decoupling from gizmo
+
+ if ( handle.tag === 'helper' ) {
+
+ handle.visible = false;
+
+ if ( handle.name === 'AXIS' ) {
+
+ handle.position.copy( this.worldPositionStart );
+ handle.visible = !! this.axis;
+
+ if ( this.axis === 'X' ) {
+
+ _tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, 0 ) );
+
+ handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
+
+ if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
+
+ handle.visible = false;
+
+ }
+
+ }
+
+ if ( this.axis === 'Y' ) {
+
+ _tempQuaternion.setFromEuler( _tempEuler.set( 0, 0, Math.PI / 2 ) );
+
+ handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
+
+ if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
+
+ handle.visible = false;
+
+ }
+
+ }
+
+ if ( this.axis === 'Z' ) {
+
+ _tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );
+
+ handle.quaternion.copy( quaternion ).multiply( _tempQuaternion );
+
+ if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > 0.9 ) {
+
+ handle.visible = false;
+
+ }
+
+ }
+
+ if ( this.axis === 'XYZE' ) {
+
+ _tempQuaternion.setFromEuler( _tempEuler.set( 0, Math.PI / 2, 0 ) );
+
+ _alignVector.copy( this.rotationAxis );
+
+ handle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( _zeroVector, _alignVector, _unitY ) );
+ handle.quaternion.multiply( _tempQuaternion );
+ handle.visible = this.dragging;
+
+ }
+
+ if ( this.axis === 'E' ) {
+
+ handle.visible = false;
+
+ }
+
+ } else if ( handle.name === 'START' ) {
+
+ handle.position.copy( this.worldPositionStart );
+ handle.visible = this.dragging;
+
+ } else if ( handle.name === 'END' ) {
+
+ handle.position.copy( this.worldPosition );
+ handle.visible = this.dragging;
+
+ } else if ( handle.name === 'DELTA' ) {
+
+ handle.position.copy( this.worldPositionStart );
+ handle.quaternion.copy( this.worldQuaternionStart );
+
+ _tempVector.set( 1e-10, 1e-10, 1e-10 ).add( this.worldPositionStart ).sub( this.worldPosition ).multiplyScalar( - 1 );
+
+ _tempVector.applyQuaternion( this.worldQuaternionStart.clone().invert() );
+
+ handle.scale.copy( _tempVector );
+ handle.visible = this.dragging;
+
+ } else {
+
+ handle.quaternion.copy( quaternion );
+
+ if ( this.dragging ) {
+
+ handle.position.copy( this.worldPositionStart );
+
+ } else {
+
+ handle.position.copy( this.worldPosition );
+
+ }
+
+ if ( this.axis ) {
+
+ handle.visible = this.axis.search( handle.name ) !== - 1;
+
+ }
+
+ } // If updating helper, skip rest of the loop
+
+
+ continue;
+
+ } // Align handles to current local or world rotation
+
+
+ handle.quaternion.copy( quaternion );
+
+ if ( this.mode === 'translate' || this.mode === 'scale' ) {
+
+ // Hide translate and scale axis facing the camera
+ const AXIS_HIDE_TRESHOLD = 0.99;
+ const PLANE_HIDE_TRESHOLD = 0.2;
+ const AXIS_FLIP_TRESHOLD = 0.0;
+
+ if ( handle.name === 'X' || handle.name === 'XYZX' ) {
+
+ if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) {
+
+ handle.scale.set( 1e-10, 1e-10, 1e-10 );
+ handle.visible = false;
+
+ }
+
+ }
+
+ if ( handle.name === 'Y' || handle.name === 'XYZY' ) {
+
+ if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) {
+
+ handle.scale.set( 1e-10, 1e-10, 1e-10 );
+ handle.visible = false;
+
+ }
+
+ }
+
+ if ( handle.name === 'Z' || handle.name === 'XYZZ' ) {
+
+ if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) > AXIS_HIDE_TRESHOLD ) {
+
+ handle.scale.set( 1e-10, 1e-10, 1e-10 );
+ handle.visible = false;
+
+ }
+
+ }
+
+ if ( handle.name === 'XY' ) {
+
+ if ( Math.abs( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) {
+
+ handle.scale.set( 1e-10, 1e-10, 1e-10 );
+ handle.visible = false;
+
+ }
+
+ }
+
+ if ( handle.name === 'YZ' ) {
+
+ if ( Math.abs( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) {
+
+ handle.scale.set( 1e-10, 1e-10, 1e-10 );
+ handle.visible = false;
+
+ }
+
+ }
+
+ if ( handle.name === 'XZ' ) {
+
+ if ( Math.abs( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) ) < PLANE_HIDE_TRESHOLD ) {
+
+ handle.scale.set( 1e-10, 1e-10, 1e-10 );
+ handle.visible = false;
+
+ }
+
+ } // Flip translate and scale axis ocluded behind another axis
+
+
+ if ( handle.name.search( 'X' ) !== - 1 ) {
+
+ if ( _alignVector.copy( _unitX ).applyQuaternion( quaternion ).dot( this.eye ) < AXIS_FLIP_TRESHOLD ) {
+
+ if ( handle.tag === 'fwd' ) {
+
+ handle.visible = false;
+
+ } else {
+
+ handle.scale.x *= - 1;
+
+ }
+
+ } else if ( handle.tag === 'bwd' ) {
+
+ handle.visible = false;
+
+ }
+
+ }
+
+ if ( handle.name.search( 'Y' ) !== - 1 ) {
+
+ if ( _alignVector.copy( _unitY ).applyQuaternion( quaternion ).dot( this.eye ) < AXIS_FLIP_TRESHOLD ) {
+
+ if ( handle.tag === 'fwd' ) {
+
+ handle.visible = false;
+
+ } else {
+
+ handle.scale.y *= - 1;
+
+ }
+
+ } else if ( handle.tag === 'bwd' ) {
+
+ handle.visible = false;
+
+ }
+
+ }
+
+ if ( handle.name.search( 'Z' ) !== - 1 ) {
+
+ if ( _alignVector.copy( _unitZ ).applyQuaternion( quaternion ).dot( this.eye ) < AXIS_FLIP_TRESHOLD ) {
+
+ if ( handle.tag === 'fwd' ) {
+
+ handle.visible = false;
+
+ } else {
+
+ handle.scale.z *= - 1;
+
+ }
+
+ } else if ( handle.tag === 'bwd' ) {
+
+ handle.visible = false;
+
+ }
+
+ }
+
+ } else if ( this.mode === 'rotate' ) {
+
+ // Align handles to current local or world rotation
+ _tempQuaternion2.copy( quaternion );
+
+ _alignVector.copy( this.eye ).applyQuaternion( _tempQuaternion.copy( quaternion ).invert() );
+
+ if ( handle.name.search( 'E' ) !== - 1 ) {
+
+ handle.quaternion.setFromRotationMatrix( _lookAtMatrix.lookAt( this.eye, _zeroVector, _unitY ) );
+
+ }
+
+ if ( handle.name === 'X' ) {
+
+ _tempQuaternion.setFromAxisAngle( _unitX, Math.atan2( - _alignVector.y, _alignVector.z ) );
+
+ _tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
+
+ handle.quaternion.copy( _tempQuaternion );
+
+ }
+
+ if ( handle.name === 'Y' ) {
+
+ _tempQuaternion.setFromAxisAngle( _unitY, Math.atan2( _alignVector.x, _alignVector.z ) );
+
+ _tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
+
+ handle.quaternion.copy( _tempQuaternion );
+
+ }
+
+ if ( handle.name === 'Z' ) {
+
+ _tempQuaternion.setFromAxisAngle( _unitZ, Math.atan2( _alignVector.y, _alignVector.x ) );
+
+ _tempQuaternion.multiplyQuaternions( _tempQuaternion2, _tempQuaternion );
+
+ handle.quaternion.copy( _tempQuaternion );
+
+ }
+
+ } // Hide disabled axes
+
+
+ handle.visible = handle.visible && ( handle.name.indexOf( 'X' ) === - 1 || this.showX );
+ handle.visible = handle.visible && ( handle.name.indexOf( 'Y' ) === - 1 || this.showY );
+ handle.visible = handle.visible && ( handle.name.indexOf( 'Z' ) === - 1 || this.showZ );
+ handle.visible = handle.visible && ( handle.name.indexOf( 'E' ) === - 1 || this.showX && this.showY && this.showZ ); // highlight selected axis
+
+ handle.material._opacity = handle.material._opacity || handle.material.opacity;
+ handle.material._color = handle.material._color || handle.material.color.clone();
+ handle.material.color.copy( handle.material._color );
+ handle.material.opacity = handle.material._opacity;
+
+ if ( ! this.enabled ) {
+
+ handle.material.opacity *= 0.5;
+ handle.material.color.lerp( new THREE.Color( 1, 1, 1 ), 0.5 );
+
+ } else if ( this.axis ) {
+
+ if ( handle.name === this.axis ) {
+
+ handle.material.opacity = 1.0;
+ handle.material.color.lerp( new THREE.Color( 1, 1, 1 ), 0.5 );
+
+ } else if ( this.axis.split( '' ).some( function ( a ) {
+
+ return handle.name === a;
+
+ } ) ) {
+
+ handle.material.opacity = 1.0;
+ handle.material.color.lerp( new THREE.Color( 1, 1, 1 ), 0.5 );
+
+ } else {
+
+ handle.material.opacity *= 0.25;
+ handle.material.color.lerp( new THREE.Color( 1, 1, 1 ), 0.5 );
+
+ }
+
+ }
+
+ }
+
+ super.updateMatrixWorld( force );
+
+ }
+
+ }
+
+ TransformControlsGizmo.prototype.isTransformControlsGizmo = true; //
+
+ class TransformControlsPlane extends THREE.Mesh {
+
+ constructor() {
+
+ super( new THREE.PlaneGeometry( 100000, 100000, 2, 2 ), new THREE.MeshBasicMaterial( {
+ visible: false,
+ wireframe: true,
+ side: THREE.DoubleSide,
+ transparent: true,
+ opacity: 0.1,
+ toneMapped: false
+ } ) );
+ this.type = 'TransformControlsPlane';
+
+ }
+
+ updateMatrixWorld( force ) {
+
+ let space = this.space;
+ this.position.copy( this.worldPosition );
+ if ( this.mode === 'scale' ) space = 'local'; // scale always oriented to local rotation
+
+ _v1.copy( _unitX ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );
+
+ _v2.copy( _unitY ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion );
+
+ _v3.copy( _unitZ ).applyQuaternion( space === 'local' ? this.worldQuaternion : _identityQuaternion ); // Align the plane for current transform mode, axis and space.
+
+
+ _alignVector.copy( _v2 );
+
+ switch ( this.mode ) {
+
+ case 'translate':
+ case 'scale':
+ switch ( this.axis ) {
+
+ case 'X':
+ _alignVector.copy( this.eye ).cross( _v1 );
+
+ _dirVector.copy( _v1 ).cross( _alignVector );
+
+ break;
+
+ case 'Y':
+ _alignVector.copy( this.eye ).cross( _v2 );
+
+ _dirVector.copy( _v2 ).cross( _alignVector );
+
+ break;
+
+ case 'Z':
+ _alignVector.copy( this.eye ).cross( _v3 );
+
+ _dirVector.copy( _v3 ).cross( _alignVector );
+
+ break;
+
+ case 'XY':
+ _dirVector.copy( _v3 );
+
+ break;
+
+ case 'YZ':
+ _dirVector.copy( _v1 );
+
+ break;
+
+ case 'XZ':
+ _alignVector.copy( _v3 );
+
+ _dirVector.copy( _v2 );
+
+ break;
+
+ case 'XYZ':
+ case 'E':
+ _dirVector.set( 0, 0, 0 );
+
+ break;
+
+ }
+
+ break;
+
+ case 'rotate':
+ default:
+ // special case for rotate
+ _dirVector.set( 0, 0, 0 );
+
+ }
+
+ if ( _dirVector.length() === 0 ) {
+
+ // If in rotate mode, make the plane parallel to camera
+ this.quaternion.copy( this.cameraQuaternion );
+
+ } else {
+
+ _tempMatrix.lookAt( _tempVector.set( 0, 0, 0 ), _dirVector, _alignVector );
+
+ this.quaternion.setFromRotationMatrix( _tempMatrix );
+
+ }
+
+ super.updateMatrixWorld( force );
+
+ }
+
+ }
+
+ TransformControlsPlane.prototype.isTransformControlsPlane = true;
+
+ THREE.TransformControls = TransformControls;
+ THREE.TransformControlsGizmo = TransformControlsGizmo;
+ THREE.TransformControlsPlane = TransformControlsPlane;
+
+} )();
diff --git a/downloads/UnrealBloomPass.js b/downloads/UnrealBloomPass.js
new file mode 100644
index 0000000..66316b3
--- /dev/null
+++ b/downloads/UnrealBloomPass.js
@@ -0,0 +1,366 @@
+( function () {
+
+ /**
+ * UnrealBloomPass is inspired by the bloom pass of Unreal Engine. It creates a
+ * mip map chain of bloom textures and blurs them with different radii. Because
+ * of the weighted combination of mips, and because larger blurs are done on
+ * higher mips, this effect provides good quality and performance.
+ *
+ * Reference:
+ * - https://docs.unrealengine.com/latest/INT/Engine/Rendering/PostProcessEffects/Bloom/
+ */
+
+ class UnrealBloomPass extends THREE.Pass {
+
+ constructor( resolution, strength, radius, threshold ) {
+
+ super();
+ this.strength = strength !== undefined ? strength : 1;
+ this.radius = radius;
+ this.threshold = threshold;
+ this.resolution = resolution !== undefined ? new THREE.Vector2( resolution.x, resolution.y ) : new THREE.Vector2( 256, 256 ); // create color only once here, reuse it later inside the render function
+
+ this.clearColor = new THREE.Color( 0, 0, 0 ); // render targets
+
+ const pars = {
+ minFilter: THREE.LinearFilter,
+ magFilter: THREE.LinearFilter,
+ format: THREE.RGBAFormat
+ };
+ this.renderTargetsHorizontal = [];
+ this.renderTargetsVertical = [];
+ this.nMips = 5;
+ let resx = Math.round( this.resolution.x / 2 );
+ let resy = Math.round( this.resolution.y / 2 );
+ this.renderTargetBright = new THREE.WebGLRenderTarget( resx, resy, pars );
+ this.renderTargetBright.texture.name = 'UnrealBloomPass.bright';
+ this.renderTargetBright.texture.generateMipmaps = false;
+
+ for ( let i = 0; i < this.nMips; i ++ ) {
+
+ const renderTargetHorizonal = new THREE.WebGLRenderTarget( resx, resy, pars );
+ renderTargetHorizonal.texture.name = 'UnrealBloomPass.h' + i;
+ renderTargetHorizonal.texture.generateMipmaps = false;
+ this.renderTargetsHorizontal.push( renderTargetHorizonal );
+ const renderTargetVertical = new THREE.WebGLRenderTarget( resx, resy, pars );
+ renderTargetVertical.texture.name = 'UnrealBloomPass.v' + i;
+ renderTargetVertical.texture.generateMipmaps = false;
+ this.renderTargetsVertical.push( renderTargetVertical );
+ resx = Math.round( resx / 2 );
+ resy = Math.round( resy / 2 );
+
+ } // luminosity high pass material
+
+
+ if ( THREE.LuminosityHighPassShader === undefined ) console.error( 'THREE.UnrealBloomPass relies on THREE.LuminosityHighPassShader' );
+ const highPassShader = THREE.LuminosityHighPassShader;
+ this.highPassUniforms = THREE.UniformsUtils.clone( highPassShader.uniforms );
+ this.highPassUniforms[ 'luminosityThreshold' ].value = threshold;
+ this.highPassUniforms[ 'smoothWidth' ].value = 0.01;
+ this.materialHighPassFilter = new THREE.ShaderMaterial( {
+ uniforms: this.highPassUniforms,
+ vertexShader: highPassShader.vertexShader,
+ fragmentShader: highPassShader.fragmentShader,
+ defines: {}
+ } ); // Gaussian Blur Materials
+
+ this.separableBlurMaterials = [];
+ const kernelSizeArray = [ 3, 5, 7, 9, 11 ];
+ resx = Math.round( this.resolution.x / 2 );
+ resy = Math.round( this.resolution.y / 2 );
+
+ for ( let i = 0; i < this.nMips; i ++ ) {
+
+ this.separableBlurMaterials.push( this.getSeperableBlurMaterial( kernelSizeArray[ i ] ) );
+ this.separableBlurMaterials[ i ].uniforms[ 'texSize' ].value = new THREE.Vector2( resx, resy );
+ resx = Math.round( resx / 2 );
+ resy = Math.round( resy / 2 );
+
+ } // Composite material
+
+
+ this.compositeMaterial = this.getCompositeMaterial( this.nMips );
+ this.compositeMaterial.uniforms[ 'blurTexture1' ].value = this.renderTargetsVertical[ 0 ].texture;
+ this.compositeMaterial.uniforms[ 'blurTexture2' ].value = this.renderTargetsVertical[ 1 ].texture;
+ this.compositeMaterial.uniforms[ 'blurTexture3' ].value = this.renderTargetsVertical[ 2 ].texture;
+ this.compositeMaterial.uniforms[ 'blurTexture4' ].value = this.renderTargetsVertical[ 3 ].texture;
+ this.compositeMaterial.uniforms[ 'blurTexture5' ].value = this.renderTargetsVertical[ 4 ].texture;
+ this.compositeMaterial.uniforms[ 'bloomStrength' ].value = strength;
+ this.compositeMaterial.uniforms[ 'bloomRadius' ].value = 0.1;
+ this.compositeMaterial.needsUpdate = true;
+ const bloomFactors = [ 1.0, 0.8, 0.6, 0.4, 0.2 ];
+ this.compositeMaterial.uniforms[ 'bloomFactors' ].value = bloomFactors;
+ this.bloomTintColors = [ new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 1, 1, 1 ), new THREE.Vector3( 1, 1, 1 ) ];
+ this.compositeMaterial.uniforms[ 'bloomTintColors' ].value = this.bloomTintColors; // copy material
+
+ if ( THREE.CopyShader === undefined ) {
+
+ console.error( 'THREE.UnrealBloomPass relies on THREE.CopyShader' );
+
+ }
+
+ const copyShader = THREE.CopyShader;
+ this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
+ this.copyUniforms[ 'opacity' ].value = 1.0;
+ this.materialCopy = new THREE.ShaderMaterial( {
+ uniforms: this.copyUniforms,
+ vertexShader: copyShader.vertexShader,
+ fragmentShader: copyShader.fragmentShader,
+ blending: THREE.AdditiveBlending,
+ depthTest: false,
+ depthWrite: false,
+ transparent: true
+ } );
+ this.enabled = true;
+ this.needsSwap = false;
+ this._oldClearColor = new THREE.Color();
+ this.oldClearAlpha = 1;
+ this.basic = new THREE.MeshBasicMaterial();
+ this.fsQuad = new THREE.FullScreenQuad( null );
+
+ }
+
+ dispose() {
+
+ for ( let i = 0; i < this.renderTargetsHorizontal.length; i ++ ) {
+
+ this.renderTargetsHorizontal[ i ].dispose();
+
+ }
+
+ for ( let i = 0; i < this.renderTargetsVertical.length; i ++ ) {
+
+ this.renderTargetsVertical[ i ].dispose();
+
+ }
+
+ this.renderTargetBright.dispose();
+
+ }
+
+ setSize( width, height ) {
+
+ let resx = Math.round( width / 2 );
+ let resy = Math.round( height / 2 );
+ this.renderTargetBright.setSize( resx, resy );
+
+ for ( let i = 0; i < this.nMips; i ++ ) {
+
+ this.renderTargetsHorizontal[ i ].setSize( resx, resy );
+ this.renderTargetsVertical[ i ].setSize( resx, resy );
+ this.separableBlurMaterials[ i ].uniforms[ 'texSize' ].value = new THREE.Vector2( resx, resy );
+ resx = Math.round( resx / 2 );
+ resy = Math.round( resy / 2 );
+
+ }
+
+ }
+
+ render( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
+
+ renderer.getClearColor( this._oldClearColor );
+ this.oldClearAlpha = renderer.getClearAlpha();
+ const oldAutoClear = renderer.autoClear;
+ renderer.autoClear = false;
+ renderer.setClearColor( this.clearColor, 0 );
+ if ( maskActive ) renderer.state.buffers.stencil.setTest( false ); // Render input to screen
+
+ if ( this.renderToScreen ) {
+
+ this.fsQuad.material = this.basic;
+ this.basic.map = readBuffer.texture;
+ renderer.setRenderTarget( null );
+ renderer.clear();
+ this.fsQuad.render( renderer );
+
+ } // 1. Extract Bright Areas
+
+
+ this.highPassUniforms[ 'tDiffuse' ].value = readBuffer.texture;
+ this.highPassUniforms[ 'luminosityThreshold' ].value = this.threshold;
+ this.fsQuad.material = this.materialHighPassFilter;
+ renderer.setRenderTarget( this.renderTargetBright );
+ renderer.clear();
+ this.fsQuad.render( renderer ); // 2. Blur All the mips progressively
+
+ let inputRenderTarget = this.renderTargetBright;
+
+ for ( let i = 0; i < this.nMips; i ++ ) {
+
+ this.fsQuad.material = this.separableBlurMaterials[ i ];
+ this.separableBlurMaterials[ i ].uniforms[ 'colorTexture' ].value = inputRenderTarget.texture;
+ this.separableBlurMaterials[ i ].uniforms[ 'direction' ].value = UnrealBloomPass.BlurDirectionX;
+ renderer.setRenderTarget( this.renderTargetsHorizontal[ i ] );
+ renderer.clear();
+ this.fsQuad.render( renderer );
+ this.separableBlurMaterials[ i ].uniforms[ 'colorTexture' ].value = this.renderTargetsHorizontal[ i ].texture;
+ this.separableBlurMaterials[ i ].uniforms[ 'direction' ].value = UnrealBloomPass.BlurDirectionY;
+ renderer.setRenderTarget( this.renderTargetsVertical[ i ] );
+ renderer.clear();
+ this.fsQuad.render( renderer );
+ inputRenderTarget = this.renderTargetsVertical[ i ];
+
+ } // Composite All the mips
+
+
+ this.fsQuad.material = this.compositeMaterial;
+ this.compositeMaterial.uniforms[ 'bloomStrength' ].value = this.strength;
+ this.compositeMaterial.uniforms[ 'bloomRadius' ].value = this.radius;
+ this.compositeMaterial.uniforms[ 'bloomTintColors' ].value = this.bloomTintColors;
+ renderer.setRenderTarget( this.renderTargetsHorizontal[ 0 ] );
+ renderer.clear();
+ this.fsQuad.render( renderer ); // Blend it additively over the input texture
+
+ this.fsQuad.material = this.materialCopy;
+ this.copyUniforms[ 'tDiffuse' ].value = this.renderTargetsHorizontal[ 0 ].texture;
+ if ( maskActive ) renderer.state.buffers.stencil.setTest( true );
+
+ if ( this.renderToScreen ) {
+
+ renderer.setRenderTarget( null );
+ this.fsQuad.render( renderer );
+
+ } else {
+
+ renderer.setRenderTarget( readBuffer );
+ this.fsQuad.render( renderer );
+
+ } // Restore renderer settings
+
+
+ renderer.setClearColor( this._oldClearColor, this.oldClearAlpha );
+ renderer.autoClear = oldAutoClear;
+
+ }
+
+ getSeperableBlurMaterial( kernelRadius ) {
+
+ return new THREE.ShaderMaterial( {
+ defines: {
+ 'KERNEL_RADIUS': kernelRadius,
+ 'SIGMA': kernelRadius
+ },
+ uniforms: {
+ 'colorTexture': {
+ value: null
+ },
+ 'texSize': {
+ value: new THREE.Vector2( 0.5, 0.5 )
+ },
+ 'direction': {
+ value: new THREE.Vector2( 0.5, 0.5 )
+ }
+ },
+ vertexShader: `varying vec2 vUv;
+ void main() {
+ vUv = uv;
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+ }`,
+ fragmentShader: `#include <common>
+ varying vec2 vUv;
+ uniform sampler2D colorTexture;
+ uniform vec2 texSize;
+ uniform vec2 direction;
+
+ float gaussianPdf(in float x, in float sigma) {
+ return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;
+ }
+ void main() {
+ vec2 invSize = 1.0 / texSize;
+ float fSigma = float(SIGMA);
+ float weightSum = gaussianPdf(0.0, fSigma);
+ vec3 diffuseSum = texture2D( colorTexture, vUv).rgb * weightSum;
+ for( int i = 1; i < KERNEL_RADIUS; i ++ ) {
+ float x = float(i);
+ float w = gaussianPdf(x, fSigma);
+ vec2 uvOffset = direction * invSize * x;
+ vec3 sample1 = texture2D( colorTexture, vUv + uvOffset).rgb;
+ vec3 sample2 = texture2D( colorTexture, vUv - uvOffset).rgb;
+ diffuseSum += (sample1 + sample2) * w;
+ weightSum += 2.0 * w;
+ }
+ gl_FragColor = vec4(diffuseSum/weightSum, 1.0);
+ }`
+ } );
+
+ }
+
+ getCompositeMaterial( nMips ) {
+
+ return new THREE.ShaderMaterial( {
+ defines: {
+ 'NUM_MIPS': nMips
+ },
+ uniforms: {
+ 'blurTexture1': {
+ value: null
+ },
+ 'blurTexture2': {
+ value: null
+ },
+ 'blurTexture3': {
+ value: null
+ },
+ 'blurTexture4': {
+ value: null
+ },
+ 'blurTexture5': {
+ value: null
+ },
+ 'dirtTexture': {
+ value: null
+ },
+ 'bloomStrength': {
+ value: 1.0
+ },
+ 'bloomFactors': {
+ value: null
+ },
+ 'bloomTintColors': {
+ value: null
+ },
+ 'bloomRadius': {
+ value: 0.0
+ }
+ },
+ vertexShader: `varying vec2 vUv;
+ void main() {
+ vUv = uv;
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
+ }`,
+ fragmentShader: `varying vec2 vUv;
+ uniform sampler2D blurTexture1;
+ uniform sampler2D blurTexture2;
+ uniform sampler2D blurTexture3;
+ uniform sampler2D blurTexture4;
+ uniform sampler2D blurTexture5;
+ uniform sampler2D dirtTexture;
+ uniform float bloomStrength;
+ uniform float bloomRadius;
+ uniform float bloomFactors[NUM_MIPS];
+ uniform vec3 bloomTintColors[NUM_MIPS];
+
+ float lerpBloomFactor(const in float factor) {
+ float mirrorFactor = 1.2 - factor;
+ return mix(factor, mirrorFactor, bloomRadius);
+ }
+
+ void main() {
+ gl_FragColor = bloomStrength * ( lerpBloomFactor(bloomFactors[0]) * vec4(bloomTintColors[0], 1.0) * texture2D(blurTexture1, vUv) +
+ lerpBloomFactor(bloomFactors[1]) * vec4(bloomTintColors[1], 1.0) * texture2D(blurTexture2, vUv) +
+ lerpBloomFactor(bloomFactors[2]) * vec4(bloomTintColors[2], 1.0) * texture2D(blurTexture3, vUv) +
+ lerpBloomFactor(bloomFactors[3]) * vec4(bloomTintColors[3], 1.0) * texture2D(blurTexture4, vUv) +
+ lerpBloomFactor(bloomFactors[4]) * vec4(bloomTintColors[4], 1.0) * texture2D(blurTexture5, vUv) );
+ }`
+ } );
+
+ }
+
+ }
+
+ UnrealBloomPass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 );
+ UnrealBloomPass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 );
+
+ THREE.UnrealBloomPass = UnrealBloomPass;
+
+} )();
diff --git a/downloads/dashboard.html b/downloads/dashboard.html
new file mode 100644
index 0000000..d4275f2
--- /dev/null
+++ b/downloads/dashboard.html
@@ -0,0 +1,643 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>newOS4 Dashboard</title>
+ <style>
+ :root {
+ --bg: #0a0f0a;
+ --surface: #0f1a0f;
+ --border: #1a3320;
+ --accent: #00ff41;
+ --accent-dim: #00cc33;
+ --accent-glow: rgba(0, 255, 65, 0.15);
+ --text: #e0ffe6;
+ --text-dim: #88aa88;
+ --warn: #ffcc00;
+ --danger: #ff4444;
+ --info: #44aaff;
+ }
+ * { box-sizing: border-box; margin: 0; padding: 0; }
+ body {
+ background: var(--bg);
+ color: var(--text);
+ font-family: 'Segoe UI', system-ui, sans-serif;
+ line-height: 1.5;
+ min-height: 100vh;
+ }
+ header {
+ border-bottom: 1px solid var(--border);
+ padding: 1rem 1.5rem;
+ background: var(--surface);
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ position: sticky;
+ top: 0;
+ z-index: 10;
+ }
+ header h1 {
+ font-size: 1.2rem;
+ color: var(--accent);
+ text-shadow: 0 0 8px var(--accent-glow);
+ }
+ header .meta {
+ font-size: 0.8rem;
+ color: var(--text-dim);
+ }
+ .header-controls {
+ display: flex;
+ gap: 0.5rem;
+ align-items: center;
+ }
+ .header-controls button {
+ background: var(--surface);
+ border: 1px solid var(--border);
+ color: var(--text);
+ padding: 0.3rem 0.8rem;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 0.8rem;
+ font-family: inherit;
+ }
+ .header-controls button:hover {
+ border-color: var(--accent);
+ color: var(--accent);
+ }
+ .header-controls .status-dot {
+ display: inline-block;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ margin-right: 4px;
+ }
+ .status-dot.green { background: var(--accent); box-shadow: 0 0 6px var(--accent); }
+ .status-dot.yellow { background: var(--warn); box-shadow: 0 0 6px var(--warn); }
+ .status-dot.red { background: var(--danger); box-shadow: 0 0 6px var(--danger); }
+ .status-dot.gray { background: var(--text-dim); }
+
+ .container { max-width: 1200px; margin: 0 auto; padding: 1rem; }
+
+ .grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
+ gap: 1rem;
+ margin-bottom: 1.5rem;
+ }
+ .panel {
+ background: var(--surface);
+ border: 1px solid var(--border);
+ border-radius: 6px;
+ padding: 1rem;
+ transition: border-color 0.3s;
+ }
+ .panel:hover { border-color: var(--accent-dim); }
+ .panel h3 {
+ font-size: 0.75rem;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ color: var(--text-dim);
+ margin-bottom: 0.5rem;
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ }
+ .panel .value {
+ font-size: 1.8rem;
+ font-weight: 700;
+ color: var(--text);
+ }
+ .panel .sub {
+ font-size: 0.75rem;
+ color: var(--text-dim);
+ margin-top: 0.2rem;
+ }
+ .panel .progress {
+ height: 4px;
+ background: #1a3320;
+ border-radius: 2px;
+ overflow: hidden;
+ margin-top: 0.5rem;
+ }
+ .panel .progress-fill {
+ height: 100%;
+ border-radius: 2px;
+ transition: width 0.5s;
+ }
+ .progress-fill.green { background: var(--accent); }
+ .progress-fill.yellow { background: var(--warn); }
+ .progress-fill.red { background: var(--danger); }
+
+ .section {
+ margin: 1.5rem 0;
+ padding: 1rem;
+ background: var(--surface);
+ border-left: 3px solid var(--accent);
+ border-radius: 0 6px 6px 0;
+ }
+ .section h2 {
+ font-size: 1rem;
+ color: var(--accent);
+ margin-bottom: 0.75rem;
+ }
+ .section.warn { border-left-color: var(--warn); }
+ .section.danger { border-left-color: var(--danger); }
+
+ table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 0.85rem;
+ }
+ th, td {
+ text-align: left;
+ padding: 0.4rem 0.6rem;
+ border-bottom: 1px solid var(--border);
+ }
+ th {
+ color: var(--accent);
+ font-weight: 600;
+ text-transform: uppercase;
+ font-size: 0.7rem;
+ letter-spacing: 0.05em;
+ }
+ td { color: var(--text); }
+ tr:hover td { background: rgba(0,255,65,0.04); }
+
+ .badge {
+ display: inline-block;
+ padding: 0.1rem 0.4rem;
+ border: 1px solid var(--border);
+ font-size: 0.7rem;
+ border-radius: 3px;
+ color: var(--text-dim);
+ }
+ .badge.green { border-color: var(--accent); color: var(--accent); }
+ .badge.yellow { border-color: var(--warn); color: var(--warn); }
+ .badge.red { border-color: var(--danger); color: var(--danger); }
+ .badge.blue { border-color: var(--info); color: var(--info); }
+
+ .agent-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0.4rem 0;
+ border-bottom: 1px dashed var(--border);
+ font-size: 0.85rem;
+ }
+ .agent-row:last-child { border-bottom: none; }
+ .agent-row .name { color: var(--text); }
+ .agent-row .status { font-size: 0.75rem; }
+ .agent-row .caps { font-size: 0.7rem; color: var(--text-dim); }
+
+ .metric-row {
+ display: flex;
+ justify-content: space-between;
+ padding: 0.3rem 0;
+ border-bottom: 1px dashed var(--border);
+ font-size: 0.85rem;
+ }
+ .metric-row:last-child { border-bottom: none; }
+
+ .loading {
+ text-align: center;
+ padding: 3rem;
+ color: var(--text-dim);
+ }
+ .loading .spinner {
+ display: inline-block;
+ width: 24px;
+ height: 24px;
+ border: 2px solid var(--border);
+ border-top-color: var(--accent);
+ border-radius: 50%;
+ animation: spin 0.8s linear infinite;
+ margin-bottom: 0.5rem;
+ }
+ @keyframes spin { to { transform: rotate(360deg); } }
+
+ .error-banner {
+ background: rgba(255,68,68,0.1);
+ border: 1px solid var(--danger);
+ color: var(--danger);
+ padding: 0.75rem;
+ border-radius: 6px;
+ margin-bottom: 1rem;
+ font-size: 0.85rem;
+ }
+
+ .last-updated {
+ text-align: center;
+ font-size: 0.7rem;
+ color: var(--text-dim);
+ padding: 1rem;
+ border-top: 1px solid var(--border);
+ margin-top: 1rem;
+ }
+
+ @media (max-width: 640px) {
+ header { padding: 0.75rem; flex-direction: column; align-items: flex-start; }
+ .container { padding: 0.75rem; }
+ .grid { grid-template-columns: 1fr 1fr; }
+ .panel .value { font-size: 1.4rem; }
+ }
+ @media (max-width: 400px) {
+ .grid { grid-template-columns: 1fr; }
+ }
+ </style>
+</head>
+<body>
+<header>
+ <div>
+ <h1>⬑ newOS4 Dashboard</h1>
+ <div class="meta">Live system telemetry Β· <span id="version-display">v?</span></div>
+ </div>
+ <div class="header-controls">
+ <span id="connection-status"><span class="status-dot gray"></span> Loading...</span>
+ <button onclick="refreshNow()">⟳ Refresh</button>
+ <button onclick="document.querySelector('.container').classList.toggle('compact')">⊞ Toggle</button>
+ </div>
+</header>
+
+<div class="container">
+ <div id="error-banner" class="error-banner" style="display:none"></div>
+
+ <div id="loading" class="loading">
+ <div class="spinner"></div>
+ <div>Connecting to newOS4...</div>
+ </div>
+
+ <div id="dashboard-content" style="display:none">
+ <!-- Metric Panels -->
+ <div class="grid" id="metric-grid">
+ <div class="panel" id="panel-modules">
+ <h3>🧩 Modules</h3>
+ <div class="value" id="val-modules">--</div>
+ <div class="sub" id="sub-modules"></div>
+ <div class="progress"><div class="progress-fill green" id="bar-modules" style="width:0%"></div></div>
+ </div>
+ <div class="panel" id="panel-agents">
+ <h3>πŸ€– Agents</h3>
+ <div class="value" id="val-agents">--</div>
+ <div class="sub" id="sub-agents"></div>
+ <div class="progress"><div class="progress-fill" id="bar-agents" style="width:0%"></div></div>
+ </div>
+ <div class="panel" id="panel-memory">
+ <h3>πŸ’Ύ Memory</h3>
+ <div class="value" id="val-memory">--</div>
+ <div class="sub" id="sub-memory"></div>
+ <div class="progress"><div class="progress-fill green" id="bar-memory" style="width:0%"></div></div>
+ </div>
+ <div class="panel" id="panel-vfs">
+ <h3>πŸ“ VFS</h3>
+ <div class="value" id="val-vfs">--</div>
+ <div class="sub" id="sub-vfs"></div>
+ <div class="progress"><div class="progress-fill green" id="bar-vfs" style="width:0%"></div></div>
+ </div>
+ <div class="panel" id="panel-ollama">
+ <h3>🧠 Ollama</h3>
+ <div class="value" id="val-ollama">--</div>
+ <div class="sub" id="sub-ollama"></div>
+ <div class="progress"><div class="progress-fill green" id="bar-ollama" style="width:0%"></div></div>
+ </div>
+ <div class="panel" id="panel-skills">
+ <h3>πŸ“š Skills</h3>
+ <div class="value" id="val-skills">--</div>
+ <div class="sub" id="sub-skills"></div>
+ <div class="progress"><div class="progress-fill green" id="bar-skills" style="width:0%"></div></div>
+ </div>
+ </div>
+
+ <!-- Agent Pool -->
+ <div class="section" id="section-agents">
+ <h2>πŸ€– Agent Pool</h2>
+ <div id="agent-list"><div class="metric-row">No agents spawned</div></div>
+ </div>
+
+ <!-- Token Usage -->
+ <div class="section" id="section-tokens">
+ <h2>πŸ“Š LLM Token Usage</h2>
+ <div id="token-summary"></div>
+ <div style="margin-top:0.5rem">
+ <table>
+ <thead><tr><th>Model</th><th>Requests</th><th>Tokens</th><th>%</th></tr></thead>
+ <tbody id="token-by-model"></tbody>
+ </table>
+ </div>
+ </div>
+
+ <!-- Tool Latency -->
+ <div class="section warn" id="section-latency">
+ <h2>⏱ Tool Latency (Top 10)</h2>
+ <table>
+ <thead><tr><th>Tool</th><th>Avg</th><th>Max</th><th>Calls</th><th>Errors</th></tr></thead>
+ <tbody id="latency-table"></tbody>
+ </table>
+ </div>
+
+ <!-- World Model -->
+ <div class="section" id="section-world-model">
+ <h2>🌐 World Model</h2>
+ <div id="world-model-metrics">
+ <div class="metric-row"><span>Not synthesized yet</span><span>β€”</span></div>
+ </div>
+ </div>
+
+ <!-- System Health -->
+ <div class="section" id="section-health">
+ <h2>🩺 System Health</h2>
+ <div id="health-metrics"></div>
+ </div>
+ </div>
+
+ <div class="last-updated">
+ Last updated: <span id="last-updated-time">--</span> Β· Auto-refresh every 5s
+ </div>
+</div>
+
+<script>
+(function() {
+ 'use strict';
+
+ const DASHBOARD_KEY = 'webx11_dashboard_data';
+ const REFRESH_INTERVAL = 5000;
+ let refreshTimer = null;
+ let lastData = null;
+
+ function showError(msg) {
+ const banner = document.getElementById('error-banner');
+ banner.textContent = '⚠️ ' + msg;
+ banner.style.display = 'block';
+ }
+
+ function hideError() {
+ document.getElementById('error-banner').style.display = 'none';
+ }
+
+ function showLoading() {
+ document.getElementById('loading').style.display = 'block';
+ document.getElementById('dashboard-content').style.display = 'none';
+ }
+
+ function showContent() {
+ document.getElementById('loading').style.display = 'none';
+ document.getElementById('dashboard-content').style.display = 'block';
+ }
+
+ function updateConnectionStatus(ok) {
+ const el = document.getElementById('connection-status');
+ if (ok) {
+ el.innerHTML = '<span class="status-dot green"></span> Connected';
+ } else {
+ el.innerHTML = '<span class="status-dot red"></span> Disconnected';
+ }
+ }
+
+ function fetchDashboardData() {
+ // Try to get data from localStorage (set by the AI tool or terminal command)
+ try {
+ const raw = localStorage.getItem(DASHBOARD_KEY);
+ if (raw) {
+ const data = JSON.parse(raw);
+ if (data && data.timestamp && (Date.now() - data.timestamp < 10000)) {
+ return data; // fresh enough
+ }
+ }
+ } catch (e) {}
+ return null;
+ }
+
+ function renderDashboard(data) {
+ if (!data) {
+ showError('No dashboard data available. Open newOS4 terminal and run: dashboard');
+ updateConnectionStatus(false);
+ return;
+ }
+
+ hideError();
+ updateConnectionStatus(true);
+ lastData = data;
+
+ // Version
+ document.getElementById('version-display').textContent = data.version || 'v?';
+
+ // ── Metric Panels ──
+ // Modules
+ const modCount = data.modules?.loaded || 0;
+ const modTotal = data.modules?.total || modCount;
+ document.getElementById('val-modules').textContent = modCount + '/' + modTotal;
+ document.getElementById('sub-modules').textContent = (data.modules?.modifiedCount || 0) + ' modified';
+ document.getElementById('bar-modules').style.width = (modTotal > 0 ? (modCount / modTotal * 100) : 0) + '%';
+
+ // Agents
+ const agents = data.agents || {};
+ const agentTotal = agents.total || 0;
+ const agentBusy = agents.busy || 0;
+ const agentIdle = agents.idle || 0;
+ document.getElementById('val-agents').textContent = agentTotal;
+ document.getElementById('sub-agents').textContent = agentBusy + ' busy, ' + agentIdle + ' idle' + (agents.sleeping ? ', ' + agents.sleeping + ' sleeping' : '');
+ const barAgents = document.getElementById('bar-agents');
+ barAgents.style.width = (agentTotal > 0 ? (agentBusy / agentTotal * 100) : 0) + '%';
+ barAgents.className = 'progress-fill ' + (agentBusy > 0 ? 'yellow' : 'green');
+
+ // Memory
+ const memStr = data.memory?.heap || 'N/A';
+ const memNum = parseFloat(memStr) || 0;
+ document.getElementById('val-memory').textContent = memStr;
+ document.getElementById('sub-memory').textContent = data.memory?.graphNodes ? data.memory.graphNodes + ' graph nodes' : '';
+ const barMem = document.getElementById('bar-memory');
+ barMem.style.width = Math.min(memNum / 2, 100) + '%';
+ barMem.className = 'progress-fill ' + (memNum > 100 ? 'yellow' : (memNum > 200 ? 'red' : 'green'));
+
+ // VFS
+ const vfs = data.vfs || {};
+ document.getElementById('val-vfs').textContent = vfs.files || 0;
+ document.getElementById('sub-vfs').textContent = (vfs.dirs || 0) + ' dirs, ' + (vfs.size || '0KB');
+ document.getElementById('bar-vfs').style.width = Math.min((vfs.files || 0) / 2, 100) + '%';
+
+ // Ollama
+ const ollama = data.ollama || {};
+ const ollamaOk = ollama.connected || false;
+ document.getElementById('val-ollama').textContent = ollamaOk ? (ollama.model || 'Connected') : 'Disconnected';
+ document.getElementById('sub-ollama').textContent = ollamaOk ? (ollama.provider || '') : '';
+ const barOllama = document.getElementById('bar-ollama');
+ barOllama.style.width = ollamaOk ? '100%' : '0%';
+ barOllama.className = 'progress-fill ' + (ollamaOk ? 'green' : 'red');
+
+ // Skills
+ const skillCount = data.skills?.count || 0;
+ document.getElementById('val-skills').textContent = skillCount;
+ document.getElementById('sub-skills').textContent = data.skills?.note || '';
+ document.getElementById('bar-skills').style.width = Math.min(skillCount * 2.5, 100) + '%';
+
+ // ── Agent Pool ──
+ const agentList = document.getElementById('agent-list');
+ if (agents.list && agents.list.length > 0) {
+ let html = '';
+ for (const a of agents.list) {
+ const statusClass = a.status === 'busy' ? 'yellow' : a.status === 'idle' ? 'green' : a.status === 'sleeping' ? 'blue' : 'red';
+ html += '<div class="agent-row">' +
+ '<div><span class="name">' + a.id + '</span> <span class="caps">[' + (a.role || 'worker') + ']</span></div>' +
+ '<div><span class="badge ' + statusClass + '">' + a.status + '</span></div>' +
+ '</div>';
+ }
+ agentList.innerHTML = html;
+ } else {
+ agentList.innerHTML = '<div class="metric-row">No agents spawned</div>';
+ }
+
+ // ── Token Usage ──
+ const tokenSection = document.getElementById('token-summary');
+ const usage = data.usage || {};
+ if (usage.total && usage.total > 0) {
+ const avgLat = usage.avgLatency || 0;
+ const totalTok = (usage.totalPrompt || 0) + (usage.totalCompletion || 0);
+ tokenSection.innerHTML =
+ '<div class="metric-row"><span>Total requests</span><span>' + usage.total + '</span></div>' +
+ '<div class="metric-row"><span>Total tokens</span><span>' + totalTok.toLocaleString() + '</span></div>' +
+ '<div class="metric-row"><span>Avg latency</span><span>' + avgLat + 'ms</span></div>';
+
+ // Per-model breakdown
+ const tbody = document.getElementById('token-by-model');
+ const byModel = usage.byModel || {};
+ const modelKeys = Object.keys(byModel);
+ if (modelKeys.length > 0) {
+ let html = '';
+ for (const model of modelKeys) {
+ const m = byModel[model];
+ const pct = totalTok > 0 ? (m.tokens / totalTok * 100).toFixed(1) : '0';
+ html += '<tr><td>' + model + '</td><td>' + m.requests + '</td><td>' + m.tokens.toLocaleString() + '</td><td>' + pct + '%</td></tr>';
+ }
+ tbody.innerHTML = html;
+ } else {
+ tbody.innerHTML = '<tr><td colspan="4" style="color:var(--text-dim)">No usage data yet</td></tr>';
+ }
+ } else {
+ tokenSection.innerHTML = '<div class="metric-row" style="color:var(--text-dim)">No usage data yet</div>';
+ document.getElementById('token-by-model').innerHTML = '<tr><td colspan="4" style="color:var(--text-dim)">Run some AI queries to see usage</td></tr>';
+ }
+
+ // ── Tool Latency ──
+ const latencyTbody = document.getElementById('latency-table');
+ const latency = data.latency || [];
+ if (latency.length > 0) {
+ let html = '';
+ for (const t of latency.slice(0, 10)) {
+ const errClass = t.errors > 0 ? ' class="yellow"' : '';
+ html += '<tr' + errClass + '><td>' + t.name + '</td><td>' + t.avg + 'ms</td><td>' + t.max + 'ms</td><td>' + t.calls + '</td><td>' + (t.errors > 0 ? '⚠️ ' + t.errors : '0') + '</td></tr>';
+ }
+ latencyTbody.innerHTML = html;
+ } else {
+ latencyTbody.innerHTML = '<tr><td colspan="5" style="color:var(--text-dim)">No latency data yet</td></tr>';
+ }
+
+ // ── World Model ──
+ const wmDiv = document.getElementById('world-model-metrics');
+ const wmData = data.worldModel;
+ if (wmData) {
+ const synTime = wmData.synthesized ? new Date(wmData.synthesized).toLocaleTimeString() : '?';
+ let wmHtml = '';
+ wmHtml += '<div class="metric-row"><span>Version</span><span>' + (wmData.version || '?') + '</span></div>';
+ wmHtml += '<div class="metric-row"><span>Last synthesized</span><span>' + synTime + '</span></div>';
+ wmHtml += '<div class="metric-row"><span>Modules</span><span>' + (wmData.modules || '?') + '</span></div>';
+ wmHtml += '<div class="metric-row"><span>Skills</span><span>' + (wmData.skills || 0) + '</span></div>';
+ wmHtml += '<div class="metric-row"><span>Files</span><span>' + (wmData.files || 0) + '</span></div>';
+ wmHtml += '<div class="metric-row"><span>Agents</span><span>' + (wmData.agents || 0) + '</span></div>';
+ wmHtml += '<div class="metric-row"><span>Memory graph</span><span>' + (wmData.memoryNodes || 0) + ' nodes, ' + (wmData.memoryEdges || 0) + ' edges</span></div>';
+ wmHtml += '<div class="metric-row"><span>Health</span><span>' + (wmData.health || '?') + '</span></div>';
+ if (wmData.activeProjects && wmData.activeProjects.length > 0) {
+ wmHtml += '<div class="metric-row"><span>Active projects</span><span>' + wmData.activeProjects.join(', ') + '</span></div>';
+ }
+ if (wmData.recent && wmData.recent.length > 0) {
+ wmHtml += '<div class="metric-row"><span>Recent changes</span><span>' + wmData.recent.join('; ') + '</span></div>';
+ }
+ wmDiv.innerHTML = wmHtml;
+ } else {
+ wmDiv.innerHTML = '<div class="metric-row" style="color:var(--text-dim)">World model not synthesized β€” run world-model-refresh in terminal</div>';
+ }
+
+ // ── System Health ──
+ const healthDiv = document.getElementById('health-metrics');
+ const health = data.health || {};
+ let healthHtml = '';
+ healthHtml += '<div class="metric-row"><span>Modules loaded</span><span>' + (health.modules || '?') + '</span></div>';
+ healthHtml += '<div class="metric-row"><span>VFS size</span><span>' + (health.vfsSize || '?') + '</span></div>';
+ healthHtml += '<div class="metric-row"><span>Online</span><span>' + (health.online ? 'βœ… Online' : 'πŸ”΄ Offline') + '</span></div>';
+ healthHtml += '<div class="metric-row"><span>Errors</span><span>' + (health.errors > 0 ? '⚠️ ' + health.errors : 'βœ… 0') + '</span></div>';
+ healthHtml += '<div class="metric-row"><span>Predictor accuracy</span><span>' + (health.predictorAccuracy || 'N/A') + '</span></div>';
+ healthDiv.innerHTML = healthHtml;
+
+ // Timestamp
+ document.getElementById('last-updated-time').textContent = new Date().toLocaleTimeString();
+ }
+
+ function refreshNow() {
+ // Signal the terminal to update dashboard data
+ try {
+ localStorage.setItem(DASHBOARD_KEY + '_request', Date.now().toString());
+ } catch (e) {}
+ // Try reading fresh data
+ const data = fetchDashboardData();
+ if (data) {
+ renderDashboard(data);
+ } else {
+ // If no data, try to fetch via the newOS4 API
+ fetchDashboardFromAPI();
+ }
+ }
+
+ async function fetchDashboardFromAPI() {
+ showLoading();
+ try {
+ // Try the proxy API endpoint
+ const resp = await fetch('/api/dashboard', { signal: AbortSignal.timeout(5000) });
+ if (resp.ok) {
+ const data = await resp.json();
+ localStorage.setItem(DASHBOARD_KEY, JSON.stringify({...data, timestamp: Date.now()}));
+ renderDashboard(data);
+ showContent();
+ return;
+ }
+ } catch (e) {
+ // API not available β€” try localStorage fallback
+ }
+
+ // Fallback: check localStorage
+ const data = fetchDashboardData();
+ if (data) {
+ renderDashboard(data);
+ showContent();
+ } else {
+ showError('Cannot connect to newOS4. Open the terminal and run: dashboard');
+ updateConnectionStatus(false);
+ showContent();
+ }
+ }
+
+ // Auto-refresh loop
+ function startAutoRefresh() {
+ if (refreshTimer) clearInterval(refreshTimer);
+ refreshTimer = setInterval(() => {
+ const data = fetchDashboardData();
+ if (data) renderDashboard(data);
+ }, REFRESH_INTERVAL);
+ }
+
+ // Init
+ const initialData = fetchDashboardData();
+ if (initialData) {
+ renderDashboard(initialData);
+ showContent();
+ } else {
+ fetchDashboardFromAPI();
+ }
+ startAutoRefresh();
+
+ // Expose refresh for the button
+ window.refreshNow = refreshNow;
+})();
+</script>
+</body>
+</html>
diff --git a/downloads/evolution_plan/gunes-uygarligi-gercekci.html b/downloads/evolution_plan/gunes-uygarligi-gercekci.html
new file mode 100644
index 0000000..5b6e352
--- /dev/null
+++ b/downloads/evolution_plan/gunes-uygarligi-gercekci.html
@@ -0,0 +1,197 @@
+<!DOCTYPE html>
+<html lang="tr">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>GΓΌneş Uygarlığı Γ— newOS4 β€” GerΓ§ekΓ§i Değerlendirme</title>
+<meta name="theme-color" content="#FF8C42">
+<style>
+* { margin: 0; padding: 0; box-sizing: border-box; }
+body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
+ background: #0a0a0a;
+ color: #e0e0e0;
+ line-height: 1.7;
+ padding: 2rem 1.5rem;
+ max-width: 680px;
+ margin: 0 auto;
+}
+h1 { font-size: 1.5rem; color: #FF8C42; margin-bottom: 0.5rem; }
+h2 { font-size: 1.15rem; color: #FF8C42; margin: 1.5rem 0 0.5rem; }
+h3 { font-size: 1rem; color: #FFD700; margin: 1rem 0 0.3rem; }
+p { margin-bottom: 0.8rem; color: #c0c0c0; }
+a { color: #FF8C42; }
+hr { border: none; border-top: 1px solid rgba(255,140,66,0.15); margin: 1.5rem 0; }
+.tag {
+ display: inline-block;
+ background: rgba(255,140,66,0.1);
+ color: #FF8C42;
+ padding: 0.15rem 0.5rem;
+ border-radius: 4px;
+ font-size: 0.8rem;
+ margin: 0.1rem;
+}
+.box {
+ border: 1px solid rgba(255,140,66,0.2);
+ border-radius: 10px;
+ padding: 1rem;
+ margin: 1rem 0;
+ background: rgba(255,140,66,0.03);
+}
+.box-green { border-color: rgba(74,222,128,0.2); background: rgba(74,222,128,0.03); }
+.box-red { border-color: rgba(248,113,113,0.2); background: rgba(248,113,113,0.03); }
+ul { list-style: none; margin: 0.5rem 0; }
+li { padding: 0.3rem 0 0.3rem 1.2rem; position: relative; color: #c0c0c0; font-size: 0.95rem; }
+li::before { content: 'β€Ί'; position: absolute; left: 0; color: #FF8C42; font-weight: bold; }
+.meta { color: #777; font-size: 0.85rem; }
+.status { font-size: 0.8rem; font-family: monospace; }
+.status-done { color: #4ade80; }
+.status-wip { color: #fbbf24; }
+.status-dream { color: #f87171; }
+</style>
+</head>
+<body>
+
+<h1>β˜€οΈ GΓΌneş Uygarlığı Γ— newOS4<br><span style="color:#888; font-size:1rem;">GerΓ§ekΓ§i Değerlendirme β€” Ne Var, Ne Yok, Ne MΓΌmkΓΌn</span></h1>
+
+<p class="meta">Temmuz 2026 Β· v4.6.10 Β· <span style="color:#FF8C42;">Sadece gerΓ§ekler, abartΔ± yok</span></p>
+
+<hr>
+
+<h2>🧠 newOS4 Nedir? (Kısa)</h2>
+<p>TarayΔ±cΔ±da Γ§alışan bir "işletim sistemi" taklidi. 44 modΓΌlΓΌ var, 90+ komutu var, iΓ§inde bir YZ ajanΔ± Γ§alışıyor. GΓΌzel tarafΔ±: tamamen aΓ§Δ±k kaynak, kendi kendini değiştirebiliyor, hafΔ±zasΔ± var. KΓΆtΓΌ tarafΔ±: tek başına bir anlam ifade etmez β€” bir kullanΔ±cΔ± ve bir LLM olmadan Γ§alışmaz.</p>
+
+<div class="box box-green">
+ <strong style="color:#4ade80;">βœ… GerΓ§ekten Γ§alışanlar:</strong>
+ <ul>
+ <li>Terminal + 90 komut β€” sağlam, her gΓΌn kullanΔ±lΔ±yor</li>
+ <li>YZ ajan dΓΆngΓΌsΓΌ β€” düşünΓΌr, araΓ§ kullanΔ±r, yineler</li>
+ <li>4 model yΓΆnlendirme β€” glm-5.2, gemma4, mistral, minimax</li>
+ <li>HafΔ±za grafiği (83 düğüm) β€” oturumlar arasΔ± bağlam</li>
+ <li>Debug Supervisor β€” hatalarΔ± yakalar, sΔ±nΔ±flandΔ±rΔ±r</li>
+ <li>WebDAV senkronizasyonu β€” yedekleme Γ§alışıyor</li>
+ </ul>
+</div>
+
+<div class="box box-red">
+ <strong style="color:#f87171;">⚠️ Abartmayalım:</strong>
+ <ul>
+ <li>"Kendini iyileştirme" = hataları kaydedip YZ'ye ânermek. Otomatik düzeltme henüz emekleme aşamasında</li>
+ <li>"Γ‡oklu ajan" = 3 basit işçi ajan. Karmaşık gΓΆrevlerde takΔ±lΔ±yor</li>
+ <li>"Neural VFS" = basit bir anlamsal arama. Google değil</li>
+ <li>17 beceri var ama Γ§oğu yarΔ±m β€” sΓΌrekli gΓΌncelleniyor</li>
+ <li>500 oturum verisi var ama hepsi aynı kalitede değil</li>
+ </ul>
+</div>
+
+<hr>
+
+<h2>β˜€οΈ newOS4, GΓΌneş Uygarlığı'na GerΓ§ekte Ne Verebilir?</h2>
+
+<p>Abartısız, bugün itibarıyla çalışan ve çalışmayan şeyler:</p>
+
+<h3>πŸ“š Eğitim β€” KΔ±smen</h3>
+<p>17 beceri modΓΌlΓΌ var. GΓΌneş enerjisi 101 iΓ§eriği yazΔ±labilir. Ama "interaktif simΓΌlasyon" falan yok β€” SimpleGUI ile basit prototipler yapΔ±labilir, o kadar. Mindmap modΓΌlΓΌ planlama iΓ§in kullanΔ±labilir. Γ‡oklu dil: YZ Γ§eviri yapabiliyor, otomatik değil.</p>
+<p class="status"><span class="status-done">βœ“ Γ‡alışan:</span> beceri sistemi, Mindmap, Γ§eviri desteği<br><span class="status-dream">βœ— Olmayan:</span> hazΔ±r gΓΌneş enerjisi eğitim iΓ§eriği, simΓΌlasyon motoru</p>
+
+<h3>🌍 Organizasyon β€” KΔ±smen</h3>
+<p>Γ‡oklu ajan sistemi var ama basit. GΓΆnΓΌllΓΌ koordinasyonu iΓ§in ΓΆzel bir modΓΌl yok β€” terminal + YZ ile idare edilebilir. A2A sΓΆzleşmeleri: modΓΌl var ama kullanΔ±mΔ± sΔ±nΔ±rlΔ±. WebDAV dosya paylaşımΔ± Γ§alışıyor, şifreleme var.</p>
+<p class="status"><span class="status-done">βœ“ Γ‡alışan:</span> WebDAV, şifreleme, ajan sistemi (basit)<br><span class="status-wip">⟳ Eksik:</span> gΓΆnΓΌllΓΌ yΓΆnetimi arayΓΌzΓΌ, A2A şablonlarΔ±</p>
+
+<h3>πŸ”¬ AraştΔ±rma β€” En GΓΌΓ§lΓΌ Alan</h3>
+<p>SearXNG + YZ ajanı ile literatür taraması yapılabiliyor. Neural VFS ile kavram bazlı arama çalışıyor. Hafıza grafiği araştırma bağlantılarını gârselleştirebilir. Bu alan gerçekten işe yarıyor.</p>
+<p class="status"><span class="status-done">βœ“ Γ‡alışan:</span> SearXNG, Neural VFS, hafΔ±za grafiği, oturum geΓ§mişi</p>
+
+<h3>πŸ—οΈ TasarΔ±m β€” Γ‡ok SΔ±nΔ±rlΔ±</h3>
+<p>SimpleGUI ile basit arayΓΌz prototipleri yapΔ±labilir. Floating UI ile etkileşimli âğeler eklenebilir. Ama "GΓΌneşkent planlama asistanΔ±" falan yok β€” bu tamamen hayal. Terminal betikleriyle enerji verisi analiz edilebilir, grafik Γ§izilebilir.</p>
+<p class="status"><span class="status-wip">⟳ YapΔ±labilir:</span> basit prototipler, veri analizi<br><span class="status-dream">βœ— Olmayan:</span> şehir planlama aracΔ±, 3B model, simΓΌlasyon</p>
+
+<h3>πŸ“’ YayΔ±n β€” İşe Yarar</h3>
+<p>Chat Studio ile manifesto yayınlanabiliyor. Cron ile otomatik paylaşım planlanabiliyor. Voice modülü var ama TTS kalitesi düşük. WPM ile içerik paketleri dağıtılabilir. Bu alan en olgun olanı.</p>
+<p class="status"><span class="status-done">βœ“ Γ‡alışan:</span> Chat Studio, Cron, WPM<br><span class="status-wip">⟳ ZayΔ±f:</span> Voice/TTS kalitesi</p>
+
+<h3>πŸ›‘οΈ SΓΌrdΓΌrΓΌlebilirlik β€” Sağlam</h3>
+<p>Debug Supervisor gerçekten hata yakalıyor ve sınıflandırıyor. Sunucu Monitâr çalışıyor. WebDAV yedekleme + şifreleme sağlam. Bu alan en güvenilir olanı.</p>
+<p class="status"><span class="status-done">βœ“ Γ‡alışan:</span> Debug Supervisor, Sunucu MonitΓΆr, yedekleme, şifreleme</p>
+
+<hr>
+
+<h2>🎯 Γ–zel Model Teklifi β€” GerΓ§ekΓ§i Bakış</h2>
+
+<p>Şu anki durum: newOS4, Ollama üzerinden 4 farklı model kullanıyor. Haftada ~500 istek, ~8M token. İşe yarıyor ama hiçbiri Güneş Uygarlığı'nı bilmiyor. Genel modellerle idare ediyoruz.</p>
+
+<p><strong style="color:#FF8C42;">Γ–zel model ne getirir?</strong></p>
+<ul>
+ <li><strong>HΔ±z:</strong> 500-2000ms β†’ 50-100ms. Bu gerΓ§ek bir kazanΓ§.</li>
+ <li><strong>Uzmanlık:</strong> Güneş enerjisi, Anadolu kültürü, manifesto bilgisi. Genel modellerin bilmediği şeyler.</li>
+ <li><strong>Bağımsızlık:</strong> Harici API yok, sansür yok, kesinti yok. Bu en büyük kazanç.</li>
+ <li><strong>Maliyet:</strong> Eğitim maliyeti var ama aylΔ±k işletme maliyeti sΔ±fΔ±r. 8M token/hafta Γ— €0.15 = €1.20/hafta tasarruf.</li>
+</ul>
+
+<p><strong style="color:#f87171;">Ama şunlar da gerçek:</strong></p>
+<ul>
+ <li>500 oturum verisi az. 8M token, bir model eğitimi için yetersiz. Sentetik genişletme şart.</li>
+ <li>CPU-only sunucuda (15GB RAM) hiçbir model çalışmaz. GPU kiralamak zorunlu.</li>
+ <li>QLoRA 14B, 1Γ— A100'de ~20 saat sΓΌrer. Bu €35-100 demek.</li>
+ <li>MoE eğitimi (Mixtral 8x7B) 2Γ— A100'de ~48 saat. €200-500.</li>
+ <li>Eğitimden sonra modeli Γ§alıştΔ±rmak iΓ§in aylΔ±k GPU kirasΔ± gerek: ~€50-200/ay.</li>
+ <li>Medusa başlıkları + MoE = araştırma seviyesi. Kolay değil.</li>
+</ul>
+
+<div class="box" style="border-color:#FF8C42;">
+ <strong style="color:#FF8C42;">πŸ’‘ En gerΓ§ekΓ§i yol:</strong>
+ <p style="font-size:0.95rem; margin-top:0.5rem;">Aşama 0 (veri seti) + Aşama 1 (QLoRA 14B) = <strong>€135-300</strong>. 1Γ— A100 kiralΔ±k, 20 saat. Γ‡Δ±kan modeli Ollama'ya yΓΌkle, dene. İşe yararsa devam et. YarΔ±mazsa €0 kayΔ±p (RAG'a dΓΆn).</p>
+</div>
+
+<hr>
+
+<h2>πŸ“‹ Γ–zet β€” Olduğu Gibi</h2>
+
+<div class="box box-green">
+ <strong style="color:#4ade80;">βœ… BugΓΌn kullanΔ±labilir:</strong>
+ <ul>
+ <li>Terminal + YZ ajanΔ± β€” gΓΌnlΓΌk iş akışı</li>
+ <li>SearXNG ile araştΔ±rma β€” literatΓΌr taramasΔ±</li>
+ <li>Chat Studio ile yayΔ±n β€” manifesto, makale</li>
+ <li>WebDAV ile dosya paylaşımΔ± β€” merkeziyetsiz arşiv</li>
+ <li>Debug Supervisor β€” hata takibi</li>
+ <li>Cron ile otomatik gΓΆrevler β€” planlΔ± paylaşım</li>
+ </ul>
+</div>
+
+<div class="box box-red">
+ <strong style="color:#f87171;">❌ Henüz olmayan / abartılı:</strong>
+ <ul>
+ <li>"GΓΌneşkent planlama asistanΔ±" β€” yok, basit prototip ancak yapΔ±lΔ±r</li>
+ <li>"Δ°nteraktif simΓΌlasyon" β€” yok, SimpleGUI ile basit demo yapΔ±labilir</li>
+ <li>"Otomatik literatΓΌr taramasΔ±" β€” SearXNG + YZ ile yarΔ±m yamalak Γ§alışır</li>
+ <li>"Kendini iyileştirme" β€” hata kaydΔ± tutar, otomatik dΓΌzeltme sΔ±nΔ±rlΔ±</li>
+ <li>"Γ–zel model" β€” €300-500 ile PoC yapΔ±labilir, tam model €8K+</li>
+ </ul>
+</div>
+
+<p style="text-align:center; color:#888; font-style:italic; margin-top:2rem; font-size:0.9rem;">
+ newOS4 sağlam bir altyapı. Ama sihirli değil.<br>
+ GΓΌneş Uygarlığı iΓ§in kullanΔ±labilir β€” doğru beklentilerle.
+</p>
+
+<hr>
+
+<p style="text-align:center;">
+ <strong>πŸ”— Tam Δ°nceleme:</strong><br>
+ <a href="https://webx11.duckdns.org/spaces/newos4/downloads/evolution_plan/gunes-uygarligi-sistem.html">webx11.duckdns.org/spaces/newos4/downloads/evolution_plan/gunes-uygarligi-sistem.html</a>
+</p>
+
+<p style="text-align:center; margin-top:1rem;">
+ <span class="tag">#GüneşUygarlığı</span>
+ <span class="tag">#newOS4</span>
+ <span class="tag">#GerΓ§ekΓ§i</span>
+</p>
+
+<p class="meta" style="text-align:center; margin-top:1.5rem;">
+ newOS4 v4.6.10 Β· Temmuz 2026<br>
+ <a href="https://webx11.duckdns.org/gunesuygarligi" style="color:#FF8C42;">🌞 Ana Kanal</a>
+</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/downloads/evolution_plan/gunes-uygarligi-newos4.html b/downloads/evolution_plan/gunes-uygarligi-newos4.html
new file mode 100644
index 0000000..92aa220
--- /dev/null
+++ b/downloads/evolution_plan/gunes-uygarligi-newos4.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html lang="tr">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>GΓΌneş Uygarlığı Γ— newOS4 β€” Dijital AltyapΔ± Δ°ncelemesi</title>
+<meta name="theme-color" content="#FFD700">
+<style>
+* { margin: 0; padding: 0; box-sizing: border-box; }
+body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
+ background: #0a0a0a;
+ color: #f4f4f4;
+ line-height: 1.7;
+ padding: 2rem 1.5rem;
+ max-width: 680px;
+ margin: 0 auto;
+}
+h1 { font-size: 1.6rem; color: #FFD700; margin-bottom: 0.5rem; }
+h2 { font-size: 1.2rem; color: #FFD700; margin: 1.5rem 0 0.5rem; }
+p { margin-bottom: 1rem; color: #d0d0d0; }
+a { color: #FFD700; text-decoration: none; }
+a:hover { text-decoration: underline; }
+hr { border: none; border-top: 1px solid rgba(255,215,0,0.15); margin: 1.5rem 0; }
+.tag {
+ display: inline-block;
+ background: rgba(255,215,0,0.1);
+ color: #FFD700;
+ padding: 0.15rem 0.5rem;
+ border-radius: 4px;
+ font-size: 0.8rem;
+ margin: 0.1rem;
+}
+.quote {
+ border-left: 3px solid #FFD700;
+ padding: 0.8rem 1rem;
+ margin: 1rem 0;
+ background: rgba(255,215,0,0.04);
+ border-radius: 0 8px 8px 0;
+ color: #b8b8b8;
+ font-style: italic;
+}
+.meta { color: #888; font-size: 0.85rem; margin-top: 1.5rem; }
+ul { list-style: none; margin: 0.5rem 0; }
+li { padding: 0.3rem 0 0.3rem 1.2rem; position: relative; color: #d0d0d0; }
+li::before { content: 'β˜€'; position: absolute; left: 0; color: #FFD700; }
+</style>
+</head>
+<body>
+
+<h1>β˜€οΈ GΓΌneş Uygarlığı Γ— newOS4<br>Dijital AltyapΔ± Δ°ncelemesi</h1>
+
+<p style="color:#888; font-size:0.9rem;">Temmuz 2026 Β· v4.6.10</p>
+
+<hr>
+
+<h2>🧠 newOS4 Nedir?</h2>
+<p>newOS4, tarayıcı tabanlı bir işletim sistemi ve içine gâmülü yapay zeka ajanıdır. 44 modül, 90+ komut, 17 beceri ve 296 dosyadan oluşan bu sistem, kendi kendini değiştirebilen, hafızası olan ve kendini iyileştirebilen bir dijital organizmadır.</p>
+
+<div class="quote">YZ sistemi işletim sisteminin beynidir β€” sohbet robotu değil, sistemin zekasΔ±.</div>
+
+<h2>β˜€οΈ GΓΌneş Uygarlığı'nΔ±n Dijital AltyapΔ±sΔ±</h2>
+<p>newOS4, Güneş Uygarlığı Hareketi'nin 6 temel ihtiyacını karşılayan entegre bir teknoloji platformudur:</p>
+
+<ul>
+ <li><strong>πŸ“š Eğitim &amp; BilinΓ§lendirme</strong> β€” 17 beceriyle gΓΌneş enerjisi eğitimi, interaktif simΓΌlasyonlar, Γ§oklu dil yayΔ±nΔ±</li>
+ <li><strong>🌍 Topluluk &amp; Organizasyon</strong> β€” Γ‡oklu ajanla gΓΆnΓΌllΓΌ koordinasyonu, A2A sΓΆzleşmeleriyle şeffaf oylama, merkeziyetsiz arşiv</li>
+ <li><strong>πŸ”¬ AraştΔ±rma &amp; Veri</strong> β€” SearXNG + YZ ile otomatik literatΓΌr taramasΔ±, Neural VFS ile anlamsal arama, hafΔ±za grafiği ile gΓΆrselleştirme</li>
+ <li><strong>πŸ—οΈ GΓΌneşkent TasarΔ±mΔ±</strong> β€” SimpleGUI ile prototip geliştirme, Floating UI ile etkileşimli haritalar, enerji veri analizi</li>
+ <li><strong>πŸ“’ YayΔ±n &amp; Δ°letişim</strong> β€” Chat Studio ile manifesto yayΔ±nΔ±, Voice ile sesli iΓ§erik, Cron ile otomatik paylaşım</li>
+ <li><strong>πŸ›‘οΈ SΓΌrdΓΌrΓΌlebilirlik</strong> β€” Kendini iyileştiren altyapΔ±, Debug Supervisor ile hata takibi, Sunucu MonitΓΆr ile enerji izleme</li>
+</ul>
+
+<h2>🎯 Γ–zel Model Teklifi</h2>
+<p>BugΓΌn newOS4, genel amaΓ§lΔ± modellerle Γ§alışıyor. Γ–zel bir model, GΓΌneş Uygarlığı'nΔ±n ihtiyaΓ§larΔ±na %100 uyumlu bir yapay zeka anlamΔ±na gelir:</p>
+
+<ul>
+ <li><strong>🌞 GΓΌneş Enerjisi Uzmanlığı</strong> β€” Panel verimliliği, akΓΌ yΓΆnetimi, yatΔ±rΔ±m geri dΓΆnüşü hesaplamalarΔ±</li>
+ <li><strong>🏘️ GΓΌneşkent Planlama AsistanΔ±</strong> β€” Bina yΓΆnlendirme, Γ§atΔ± aΓ§Δ±sΔ±, topluluk şebekesi tasarΔ±mΔ±</li>
+ <li><strong>πŸ“– KΓΌltΓΌrel &amp; Tarihsel Bağlam</strong> β€” Anadolu gΓΌneş kΓΌltΓΌrΓΌ, Hitit GΓΌneş Kursu, manifesto felsefesi</li>
+ <li><strong>🀝 Topluluk YΓΆnetişimi</strong> β€” A2A sΓΆzleşmeleri, oylama analizi, gΓΆnΓΌllΓΌ eşleştirme</li>
+ <li><strong>πŸ”’ BağımsΔ±zlΔ±k &amp; Egemenlik</strong> β€” Harici API yok, tam dijital egemenlik, sansΓΌrsΓΌz</li>
+</ul>
+
+<div class="quote">Γ–zel bir model, GΓΌneş Uygarlığı'nΔ± sadece bir teknoloji kullanΔ±cΔ±sΔ± olmaktan Γ§Δ±karΔ±p, kendi zekasΔ±nΔ± kendi kontrol eden bir harekete dΓΆnüştΓΌrΓΌr.</div>
+
+<h2>πŸ”¬ Eğitim SΓΌreci</h2>
+<p>5 aşamalΔ± bir yol haritasΔ± β€” veri seti mΓΌhendisliğinden ΓΆzel MoE modeline:</p>
+<ul>
+ <li><strong>Aşama 0:</strong> Veri Seti MΓΌhendisliği (€100-200)</li>
+ <li><strong>Aşama 1:</strong> QLoRA Kavram KanΔ±tΔ± (€35-100)</li>
+ <li><strong>Aşama 2:</strong> MoE Δ°nce AyarΔ± (€200-500)</li>
+ <li><strong>Aşama 3:</strong> Derin MoE + Γ‡oklu Token (€2,000-8,000)</li>
+ <li><strong>Aşama 4:</strong> Dağıtım &amp; Entegrasyon</li>
+</ul>
+
+<p style="text-align:center; background:rgba(255,215,0,0.08); border:1px solid #FFD700; border-radius:12px; padding:1.5rem; margin:1.5rem 0;">
+ <strong style="color:#FFD700; font-size:1.3rem;">€300-500</strong><br>
+ <span style="color:#b8b8b8;">Aşama 0+1 β€” Kavram KanΔ±tΔ±</span><br>
+ <span style="color:#888; font-size:0.85rem;">Konsepti kanıtlar. Geri kalan her şey isteğe bağlıdır.</span>
+</p>
+
+<hr>
+
+<h2>πŸ“‹ Γ–zet</h2>
+<p><strong style="color:#FFD700;">Bugün var olanlar:</strong> 44 modül, 4 model, çoklu ajan sistemi, hafıza grafiği, kendini iyileştirme, 500+ oturum verisi, sıfır harici API maliyeti.</p>
+<p><strong style="color:#FFD700;">Γ–zel eğitimle gelecek:</strong> 50-100ms yanΔ±t sΓΌresi, GΓΌneş Uygarlığı uzmanlığı, tam dijital egemenlik, sΓΌrekli kendini gΓΌncelleme, €300-500 ile başlar.</p>
+
+<div class="quote" style="text-align:center; border:none; font-style:normal;">
+ Bu bir ürün tanıtımı değil.<br>
+ Bu, bir sisteme kendi beynini verme planΔ±dΔ±r.
+</div>
+
+<hr>
+
+<p style="text-align:center;">
+ <strong>πŸ”— Δ°nceleme Belgesi:</strong><br>
+ <a href="https://webx11.duckdns.org/spaces/newos4/downloads/evolution_plan/gunes-uygarligi-sistem.html">webx11.duckdns.org/spaces/newos4/downloads/evolution_plan/gunes-uygarligi-sistem.html</a>
+</p>
+
+<p style="text-align:center; margin-top:1rem;">
+ <span class="tag">#GüneşUygarlığı</span>
+ <span class="tag">#newOS4</span>
+ <span class="tag">#SolarCivilization</span>
+ <span class="tag">#YapayZeka</span>
+ <span class="tag">#AΓ§Δ±kKaynak</span>
+</p>
+
+<p class="meta" style="text-align:center;">
+ Güneş Uygarlığı Hareketi · newOS4 v4.6.10 · Temmuz 2026<br>
+ <a href="https://webx11.duckdns.org/gunesuygarligi">🌞 Ana Kanal</a>
+</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/downloads/evolution_plan/gunes-uygarligi-sistem.html b/downloads/evolution_plan/gunes-uygarligi-sistem.html
new file mode 100644
index 0000000..5460739
--- /dev/null
+++ b/downloads/evolution_plan/gunes-uygarligi-sistem.html
@@ -0,0 +1,403 @@
+<!DOCTYPE html>
+<html lang="tr">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>GΓΌneş Uygarlığı Γ— newOS4 β€” GerΓ§ekΓ§i Değerlendirme</title>
+<meta name="description" content="Güneş Uygarlığı Hareketi için newOS4: ne var, ne yok, ne mümkün. Abartısız, sadece gerçekler.">
+<meta name="theme-color" content="#FF8C42">
+<meta name="color-scheme" content="dark">
+
+<style>
+:root {
+ --bg: #0a0a0a;
+ --bg-soft: #141414;
+ --bg-elev: #1c1c1c;
+ --fg: #e0e0e0;
+ --fg-dim: #b0b0b0;
+ --fg-mute: #777;
+ --gold: #FFD700;
+ --dawn: #FF8C42;
+ --green: #4ade80;
+ --red: #f87171;
+ --yellow: #fbbf24;
+ --line: rgba(255,140,66,0.15);
+ --line-soft: rgba(255,255,255,0.06);
+ --font: system-ui, -apple-system, 'Segoe UI', sans-serif;
+ --font-mono: 'SF Mono', 'Cascadia Code', ui-monospace, monospace;
+}
+*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
+html { scroll-behavior: smooth; }
+body {
+ font-family: var(--font);
+ font-size: 1rem;
+ line-height: 1.7;
+ color: var(--fg);
+ background: var(--bg);
+ background-image: radial-gradient(ellipse at top, rgba(255,140,66,0.04) 0%, transparent 50%);
+ min-height: 100vh;
+}
+h1, h2, h3 { font-weight: 600; line-height: 1.3; }
+h1 { font-size: 1.5rem; color: var(--dawn); margin-bottom: 0.3rem; }
+h2 { font-size: 1.2rem; color: var(--dawn); margin: 2rem 0 0.5rem; }
+h3 { font-size: 1.05rem; color: var(--gold); margin: 1.2rem 0 0.3rem; }
+p { margin-bottom: 0.8rem; color: var(--fg-dim); max-width: 68ch; }
+a { color: var(--dawn); text-decoration: none; }
+a:hover { text-decoration: underline; }
+
+.wrapper {
+ max-width: 680px;
+ margin: 0 auto;
+ padding: 2rem 1.5rem 4rem;
+}
+
+/* Hero */
+.hero { text-align: center; padding: 2rem 0 1.5rem; border-bottom: 1px solid var(--line); margin-bottom: 2rem; }
+.hero .subtitle { color: var(--fg-mute); font-size: 0.9rem; margin-top: 0.5rem; }
+
+/* Tags */
+.tag {
+ display: inline-block;
+ background: rgba(255,140,66,0.1);
+ color: var(--dawn);
+ padding: 0.15rem 0.5rem;
+ border-radius: 4px;
+ font-size: 0.8rem;
+ margin: 0.1rem;
+ font-family: var(--font-mono);
+}
+
+/* Boxes */
+.box {
+ border: 1px solid var(--line);
+ border-radius: 10px;
+ padding: 1rem 1.2rem;
+ margin: 1rem 0;
+ background: rgba(255,140,66,0.03);
+}
+.box-green { border-color: rgba(74,222,128,0.2); background: rgba(74,222,128,0.03); }
+.box-red { border-color: rgba(248,113,113,0.2); background: rgba(248,113,113,0.03); }
+.box-gold { border-color: rgba(255,215,0,0.2); background: rgba(255,215,0,0.03); }
+
+/* Lists */
+ul { list-style: none; margin: 0.5rem 0; }
+li { padding: 0.25rem 0 0.25rem 1.2rem; position: relative; color: var(--fg-dim); font-size: 0.95rem; }
+li::before { content: 'β€Ί'; position: absolute; left: 0; color: var(--dawn); font-weight: bold; }
+
+/* Status labels */
+.status { font-size: 0.8rem; font-family: var(--font-mono); margin: 0.3rem 0 0.8rem; }
+.status-done { color: var(--green); }
+.status-wip { color: var(--yellow); }
+.status-dream { color: var(--red); }
+
+/* Section */
+.section { margin-bottom: 1.5rem; padding-bottom: 1.5rem; border-bottom: 1px solid var(--line-soft); }
+.section:last-child { border-bottom: none; }
+
+/* TOC */
+.toc { margin: 1rem 0; }
+.toc a {
+ display: block;
+ padding: 0.4rem 0.75rem;
+ color: var(--fg-dim);
+ border-left: 2px solid var(--line);
+ margin-bottom: 0.2rem;
+ font-size: 0.9rem;
+ transition: all 0.2s;
+}
+.toc a:hover { color: var(--dawn); border-left-color: var(--dawn); padding-left: 1rem; }
+
+/* Two col */
+.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin: 1rem 0; }
+@media (max-width: 600px) { .two-col { grid-template-columns: 1fr; } }
+
+/* Phase grid */
+.phase-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 0.6rem; margin: 1rem 0; }
+.phase-card {
+ background: var(--bg-elev);
+ border: 1px solid var(--line-soft);
+ border-radius: 10px;
+ padding: 0.8rem;
+ text-align: center;
+}
+.phase-card .phase-icon { font-size: 1.4rem; margin-bottom: 0.3rem; }
+.phase-card h4 { font-size: 0.9rem; color: var(--gold); font-weight: 600; }
+.phase-card p { font-size: 0.8rem; color: var(--fg-mute); margin: 0; }
+
+/* Ask box */
+.ask-box {
+ border: 1px solid var(--dawn);
+ border-radius: 12px;
+ padding: 1.5rem;
+ text-align: center;
+ margin: 1.5rem 0;
+ background: rgba(255,140,66,0.05);
+}
+.ask-box .amount { font-size: 2rem; color: var(--dawn); font-weight: 700; }
+.ask-box .sub { color: var(--fg-dim); font-size: 1rem; }
+
+/* Highlight */
+.highlight { background: rgba(255,140,66,0.05); border-left: 3px solid var(--dawn); padding: 0.8rem 1rem; margin: 1rem 0; border-radius: 0 8px 8px 0; }
+
+.meta { color: var(--fg-mute); font-size: 0.85rem; }
+.mono { font-family: var(--font-mono); font-size: 0.85rem; }
+
+/* Scrollspy active state via JS */
+.toc a.active { color: var(--dawn); border-left-color: var(--dawn); padding-left: 1rem; }
+
+@media (max-width: 480px) {
+ .wrapper { padding: 1.5rem 1rem 3rem; }
+ h1 { font-size: 1.3rem; }
+}
+</style>
+</head>
+<body>
+
+<div class="wrapper">
+
+ <!-- HERO -->
+ <div class="hero">
+ <h1>β˜€οΈ GΓΌneş Uygarlığı Γ— newOS4</h1>
+ <p style="font-size:1.1rem; color:var(--fg-dim);">GerΓ§ekΓ§i Değerlendirme β€” Ne Var, Ne Yok, Ne MΓΌmkΓΌn</p>
+ <p class="subtitle">Temmuz 2026 Β· newOS4 v4.6.10 Β· <span style="color:var(--dawn);">Sadece gerΓ§ekler, abartΔ± yok</span></p>
+ </div>
+
+ <!-- TOC -->
+ <div class="section">
+ <div class="toc" id="toc">
+ <a href="#nedir">🧠 newOS4 Nedir?</a>
+ <a href="#calisan">βœ… GerΓ§ekten Γ‡alışanlar</a>
+ <a href="#abarti">⚠️ Abartmayalım</a>
+ <a href="#gunes">β˜€οΈ GΓΌneş Uygarlığı'na KatkΔ±lar</a>
+ <a href="#ozel-model">🎯 Γ–zel Model β€” GerΓ§ekΓ§i Bakış</a>
+ <a href="#egitim">πŸ”¬ Eğitim SΓΌreci & Maliyetler</a>
+ <a href="#ozet">πŸ“‹ Γ–zet β€” Olduğu Gibi</a>
+ </div>
+ </div>
+
+ <!-- 1. newOS4 Nedir -->
+ <div class="section" id="nedir">
+ <h2>🧠 newOS4 Nedir? (Kısa)</h2>
+ <p>TarayΔ±cΔ±da Γ§alışan bir "işletim sistemi" taklidi. 44 modΓΌlΓΌ var, 90+ komutu var, iΓ§inde bir YZ ajanΔ± Γ§alışıyor. GΓΌzel tarafΔ±: tamamen aΓ§Δ±k kaynak, kendi kendini değiştirebiliyor, hafΔ±zasΔ± var. KΓΆtΓΌ tarafΔ±: tek başına bir anlam ifade etmez β€” bir kullanΔ±cΔ± ve bir LLM olmadan Γ§alışmaz.</p>
+ </div>
+
+ <!-- 2. Γ‡alışanlar -->
+ <div class="section" id="calisan">
+ <h2>βœ… GerΓ§ekten Γ‡alışanlar</h2>
+ <div class="box box-green">
+ <ul>
+ <li><strong>Terminal + 90 komut</strong> β€” sağlam, her gΓΌn kullanΔ±lΔ±yor</li>
+ <li><strong>YZ ajan dΓΆngΓΌsΓΌ</strong> β€” düşünΓΌr, araΓ§ kullanΔ±r, yineler</li>
+ <li><strong>4 model yΓΆnlendirme</strong> β€” glm-5.2, gemma4, mistral, minimax</li>
+ <li><strong>HafΔ±za grafiği</strong> (83 düğüm) β€” oturumlar arasΔ± bağlam</li>
+ <li><strong>Debug Supervisor</strong> β€” hatalarΔ± yakalar, sΔ±nΔ±flandΔ±rΔ±r</li>
+ <li><strong>WebDAV senkronizasyonu</strong> β€” yedekleme Γ§alışıyor</li>
+ <li><strong>SearXNG arama</strong> β€” web ve literatΓΌr taramasΔ±</li>
+ <li><strong>Chat Studio</strong> β€” manifesto ve makale yayΔ±nΔ±</li>
+ <li><strong>Cron</strong> β€” otomatik gΓΆrev planlama</li>
+ <li><strong>Şifreleme + Gzip</strong> β€” gΓΌvenli depolama</li>
+ </ul>
+ </div>
+ </div>
+
+ <!-- 3. AbartmayalΔ±m -->
+ <div class="section" id="abarti">
+ <h2>⚠️ Abartmayalım</h2>
+ <div class="box box-red">
+ <ul>
+ <li><strong>"Kendini iyileştirme"</strong> = hataları kaydedip YZ'ye ânermek. Otomatik düzeltme henüz emekleme aşamasında</li>
+ <li><strong>"Γ‡oklu ajan"</strong> = 3 basit işçi ajan. Karmaşık gΓΆrevlerde takΔ±lΔ±yor</li>
+ <li><strong>"Neural VFS"</strong> = basit bir anlamsal arama. Google değil</li>
+ <li><strong>17 beceri</strong> var ama Γ§oğu yarΔ±m β€” sΓΌrekli gΓΌncelleniyor</li>
+ <li><strong>500 oturum verisi</strong> var ama hepsi aynı kalitede değil</li>
+ <li><strong>Voice/TTS</strong> kalitesi düşük, pek kullanışlı değil</li>
+ <li><strong>SimpleGUI</strong> ile simülasyon değil, ancak basit prototip yapılabilir</li>
+ </ul>
+ </div>
+ </div>
+
+ <!-- 4. Güneş Uygarlığı'na Katkılar -->
+ <div class="section" id="gunes">
+ <h2>β˜€οΈ newOS4, GΓΌneş Uygarlığı'na GerΓ§ekte Ne Verebilir?</h2>
+ <p>Abartısız, bugün itibarıyla çalışan ve çalışmayan şeyler:</p>
+
+ <h3>πŸ“š Eğitim β€” KΔ±smen</h3>
+ <p>17 beceri modΓΌlΓΌ var. GΓΌneş enerjisi 101 iΓ§eriği yazΔ±labilir. Ama "interaktif simΓΌlasyon" falan yok β€” SimpleGUI ile basit prototipler yapΔ±labilir, o kadar. Mindmap modΓΌlΓΌ planlama iΓ§in kullanΔ±labilir. Γ‡oklu dil: YZ Γ§eviri yapabiliyor, otomatik değil.</p>
+ <p class="status"><span class="status-done">βœ“ Γ‡alışan:</span> beceri sistemi, Mindmap, Γ§eviri desteği &nbsp; <span class="status-dream">βœ— Olmayan:</span> hazΔ±r gΓΌneş enerjisi eğitim iΓ§eriği, simΓΌlasyon motoru</p>
+
+ <h3>🌍 Organizasyon β€” KΔ±smen</h3>
+ <p>Γ‡oklu ajan sistemi var ama basit. GΓΆnΓΌllΓΌ koordinasyonu iΓ§in ΓΆzel bir modΓΌl yok β€” terminal + YZ ile idare edilebilir. A2A sΓΆzleşmeleri: modΓΌl var ama kullanΔ±mΔ± sΔ±nΔ±rlΔ±. WebDAV dosya paylaşımΔ± Γ§alışıyor, şifreleme var.</p>
+ <p class="status"><span class="status-done">βœ“ Γ‡alışan:</span> WebDAV, şifreleme, ajan sistemi (basit) &nbsp; <span class="status-wip">⟳ Eksik:</span> gΓΆnΓΌllΓΌ yΓΆnetimi arayΓΌzΓΌ, A2A şablonlarΔ±</p>
+
+ <h3>πŸ”¬ AraştΔ±rma β€” En GΓΌΓ§lΓΌ Alan</h3>
+ <p>SearXNG + YZ ajanı ile literatür taraması yapılabiliyor. Neural VFS ile kavram bazlı arama çalışıyor. Hafıza grafiği araştırma bağlantılarını gârselleştirebilir. Bu alan gerçekten işe yarıyor.</p>
+ <p class="status"><span class="status-done">βœ“ Γ‡alışan:</span> SearXNG, Neural VFS, hafΔ±za grafiği, oturum geΓ§mişi</p>
+
+ <h3>πŸ—οΈ TasarΔ±m β€” Γ‡ok SΔ±nΔ±rlΔ±</h3>
+ <p>SimpleGUI ile basit arayΓΌz prototipleri yapΔ±labilir. Floating UI ile etkileşimli âğeler eklenebilir. Ama "GΓΌneşkent planlama asistanΔ±" falan yok β€” bu tamamen hayal. Terminal betikleriyle enerji verisi analiz edilebilir, grafik Γ§izilebilir.</p>
+ <p class="status"><span class="status-wip">⟳ YapΔ±labilir:</span> basit prototipler, veri analizi &nbsp; <span class="status-dream">βœ— Olmayan:</span> şehir planlama aracΔ±, 3B model, simΓΌlasyon</p>
+
+ <h3>πŸ“’ YayΔ±n β€” İşe Yarar</h3>
+ <p>Chat Studio ile manifesto yayınlanabiliyor. Cron ile otomatik paylaşım planlanabiliyor. Voice modülü var ama TTS kalitesi düşük. WPM ile içerik paketleri dağıtılabilir. Bu alan en olgun olanı.</p>
+ <p class="status"><span class="status-done">βœ“ Γ‡alışan:</span> Chat Studio, Cron, WPM &nbsp; <span class="status-wip">⟳ ZayΔ±f:</span> Voice/TTS kalitesi</p>
+
+ <h3>πŸ›‘οΈ SΓΌrdΓΌrΓΌlebilirlik β€” Sağlam</h3>
+ <p>Debug Supervisor gerçekten hata yakalıyor ve sınıflandırıyor. Sunucu Monitâr çalışıyor. WebDAV yedekleme + şifreleme sağlam. Bu alan en güvenilir olanı.</p>
+ <p class="status"><span class="status-done">βœ“ Γ‡alışan:</span> Debug Supervisor, Sunucu MonitΓΆr, yedekleme, şifreleme</p>
+
+ <div class="highlight">
+ <p style="margin:0; font-size:0.9rem;"><strong style="color:var(--dawn);">Γ–zet:</strong> newOS4'ΓΌn GΓΌneş Uygarlığı'na en bΓΌyΓΌk katkΔ±sΔ± araştΔ±rma, yayΔ±n ve altyapΔ± alanlarΔ±nda. Eğitim ve tasarΔ±m iΓ§in ΓΆzel iΓ§erik geliştirmek gerek. Organizasyon iΓ§in mevcut araΓ§lar idare eder ama ΓΆzel bir Γ§ΓΆzΓΌm daha iyi olur.</p>
+ </div>
+ </div>
+
+ <!-- 5. Γ–zel Model -->
+ <div class="section" id="ozel-model">
+ <h2>🎯 Γ–zel Model β€” GerΓ§ekΓ§i Bakış</h2>
+ <p>Şu anki durum: newOS4, Ollama üzerinden 4 farklı model kullanıyor. Haftada ~500 istek, ~8M token. İşe yarıyor ama hiçbiri Güneş Uygarlığı'nı bilmiyor. Genel modellerle idare ediyoruz.</p>
+
+ <div class="two-col">
+ <div class="box box-green">
+ <strong style="color:var(--green);">βœ… Γ–zel modelin gerΓ§ek kazanΓ§larΔ±:</strong>
+ <ul>
+ <li><strong>HΔ±z:</strong> 500-2000ms β†’ 50-100ms. Bu gerΓ§ek bir kazanΓ§.</li>
+ <li><strong>Uzmanlık:</strong> Güneş enerjisi, Anadolu kültürü, manifesto bilgisi</li>
+ <li><strong>Bağımsızlık:</strong> Harici API yok, sansür yok, kesinti yok</li>
+ <li><strong>Maliyet:</strong> Aylık işletme maliyeti sıfır (GPU kirası hariç)</li>
+ </ul>
+ </div>
+ <div class="box box-red">
+ <strong style="color:var(--red);">⚠️ Ama şunlar da gerçek:</strong>
+ <ul>
+ <li>500 oturum / 8M token az. Sentetik genişletme şart</li>
+ <li>CPU-only sunucuda (15GB RAM) hiçbir model çalışmaz</li>
+ <li>GPU kiralamak zorunlu: ~€50-200/ay</li>
+ <li>MoE + Medusa = araştırma seviyesi, kolay değil</li>
+ <li>Eğitim başarΔ±sΔ±z olursa € boşa gider</li>
+ </ul>
+ </div>
+ </div>
+
+ <div class="box box-gold">
+ <strong style="color:var(--gold);">πŸ’‘ En gerΓ§ekΓ§i yol:</strong>
+ <p style="font-size:0.95rem; margin-top:0.5rem;">Aşama 0 (veri seti) + Aşama 1 (QLoRA 14B) = <strong>€135-300</strong>. 1Γ— A100 kiralΔ±k, 20 saat. Γ‡Δ±kan modeli Ollama'ya yΓΌkle, dene. İşe yararsa devam et. YarΔ±mazsa €0 kayΔ±p (RAG'a dΓΆn).</p>
+ </div>
+ </div>
+
+ <!-- 6. Eğitim Süreci -->
+ <div class="section" id="egitim">
+ <h2>πŸ”¬ Eğitim SΓΌreci & Maliyetler</h2>
+ <p>5 aşamalΔ± yol haritasΔ± β€” gerΓ§ekΓ§i maliyetlerle:</p>
+ <div class="phase-grid">
+ <div class="phase-card" style="border-color:rgba(74,222,128,0.3);">
+ <div class="phase-icon" style="color:var(--green);">0</div>
+ <h4>Veri Seti</h4>
+ <p>€100-200<br>500 oturum β†’ eğitim verisi</p>
+ </div>
+ <div class="phase-card" style="border-color:rgba(74,222,128,0.3);">
+ <div class="phase-icon" style="color:var(--green);">1</div>
+ <h4>QLoRA PoC</h4>
+ <p>€35-100<br>14B, 1Γ— A100, 20 saat</p>
+ </div>
+ <div class="phase-card" style="border-color:rgba(255,191,36,0.3);">
+ <div class="phase-icon" style="color:var(--yellow);">2</div>
+ <h4>MoE Δ°nce Ayar</h4>
+ <p>€200-500<br>Mixtral 8x7B, 2Γ— A100</p>
+ </div>
+ <div class="phase-card" style="border-color:rgba(248,113,113,0.3);">
+ <div class="phase-icon" style="color:var(--red);">3</div>
+ <h4>Derin MoE</h4>
+ <p>€2,000-8,000<br>8Γ— H100, 72 saat</p>
+ </div>
+ <div class="phase-card" style="border-color:rgba(255,140,66,0.3);">
+ <div class="phase-icon" style="color:var(--dawn);">4</div>
+ <h4>Dağıtım</h4>
+ <p>€50-200/ay<br>GPU kirasΔ± + Ollama</p>
+ </div>
+ </div>
+
+ <div class="ask-box">
+ <p style="font-size:0.85rem; color:var(--fg-mute); margin-bottom:0.3rem;">En gerçekçi başlangıç:</p>
+ <div class="amount">€135-300</div>
+ <p class="sub">Aşama 0+1 β€” Kavram KanΔ±tΔ±</p>
+ <p style="font-size:0.85rem; color:var(--fg-mute); margin-top:0.5rem;">Konsepti kanıtlar. Gerisi isteğe bağlı. Başarısız olursa RAG'a dânülür.</p>
+ </div>
+ </div>
+
+ <!-- 7. Γ–zet -->
+ <div class="section" id="ozet">
+ <h2>πŸ“‹ Γ–zet β€” Olduğu Gibi</h2>
+
+ <div class="two-col">
+ <div class="box box-green">
+ <strong style="color:var(--green);">βœ… BugΓΌn kullanΔ±labilir:</strong>
+ <ul>
+ <li>Terminal + YZ ajanΔ± β€” gΓΌnlΓΌk iş akışı</li>
+ <li>SearXNG ile araştΔ±rma β€” literatΓΌr taramasΔ±</li>
+ <li>Chat Studio ile yayΔ±n β€” manifesto, makale</li>
+ <li>WebDAV ile dosya paylaşımı</li>
+ <li>Debug Supervisor β€” hata takibi</li>
+ <li>Cron ile otomatik gΓΆrevler</li>
+ <li>Şifreleme + yedekleme</li>
+ </ul>
+ </div>
+ <div class="box box-red">
+ <strong style="color:var(--red);">❌ Henüz olmayan / abartılı:</strong>
+ <ul>
+ <li>"GΓΌneşkent planlama asistanΔ±" β€” yok</li>
+ <li>"Δ°nteraktif simΓΌlasyon" β€” yok</li>
+ <li>"Otomatik literatΓΌr" β€” yarΔ±m yamalak</li>
+ <li>"Kendini iyileştirme" β€” sΔ±nΔ±rlΔ±</li>
+ <li>"Γ–zel model" β€” PoC €135-300, tam €8K+</li>
+ <li>"Γ‡oklu ajan" β€” basit, karmaşık gΓΆrevlerde takΔ±lΔ±r</li>
+ </ul>
+ </div>
+ </div>
+
+ <div class="highlight" style="text-align:center; border-left:none; border:1px solid var(--line);">
+ <p style="margin:0; color:var(--fg-mute); font-style:italic; font-size:0.9rem;">
+ newOS4 sağlam bir altyapı. Ama sihirli değil.<br>
+ GΓΌneş Uygarlığı iΓ§in kullanΔ±labilir β€” doğru beklentilerle.
+ </p>
+ </div>
+
+ <p style="text-align:center; margin-top:2rem;">
+ <span class="tag">#GüneşUygarlığı</span>
+ <span class="tag">#newOS4</span>
+ <span class="tag">#GerΓ§ekΓ§i</span>
+ </p>
+
+ <p class="meta" style="text-align:center; margin-top:1.5rem;">
+ newOS4 v4.6.10 Β· Temmuz 2026<br>
+ <a href="https://webx11.duckdns.org/gunesuygarligi" style="color:var(--dawn);">🌞 Ana Kanal</a>
+ </p>
+ </div>
+
+</div><!-- /wrapper -->
+
+<!-- Minimal TOC scrollspy (tiny JS, no libraries) -->
+<script>
+(function(){
+ var tocLinks = document.querySelectorAll('#toc a');
+ var sections = [];
+ tocLinks.forEach(function(a){
+ var id = a.getAttribute('href').substring(1);
+ var el = document.getElementById(id);
+ if(el) sections.push({el: el, link: a});
+ });
+ function update(){
+ var scrollY = window.scrollY + 100;
+ var active = null;
+ for(var i=0; i<sections.length; i++){
+ var s = sections[i];
+ if(s.el.offsetTop <= scrollY) active = s;
+ }
+ tocLinks.forEach(function(a){ a.classList.remove('active'); });
+ if(active) active.link.classList.add('active');
+ }
+ window.addEventListener('scroll', update);
+ update();
+})();
+</script>
+
+</body>
+</html>
diff --git a/downloads/evolution_plan/presentation.html b/downloads/evolution_plan/presentation.html
new file mode 100644
index 0000000..9830d4e
--- /dev/null
+++ b/downloads/evolution_plan/presentation.html
@@ -0,0 +1,812 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<meta name="apple-mobile-web-app-capable" content="yes">
+<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
+<meta name="theme-color" content="#0d0d0d">
+<title>πŸ”₯ Core Model Evolution β€” Presentation</title>
+<style>
+:root{
+ --bg:#0d0d0d;--panel:#1a1a1a;--panel2:#222;--border:#333;
+ --accent:#ff4d4d;--accent2:#ff8c8c;--gold:#ffca28;
+ --green:#4caf50;--blue:#42a5f5;--text:#e0e0e0;--muted:#888;
+}
+*{box-sizing:border-box;margin:0;padding:0}
+html,body{height:100%;overflow:hidden}
+body{
+ font-family:-apple-system,'Segoe UI',sans-serif;
+ line-height:1.65;color:var(--text);background:var(--bg);
+ -webkit-tap-highlight-color:transparent;
+ -webkit-font-smoothing:antialiased;
+}
+
+/* ── Slide System ── */
+#deck{height:100vh;height:100dvh;width:100vw;overflow:hidden;position:relative}
+.slide{
+ position:absolute;top:0;left:0;width:100%;height:100%;
+ padding:20px 18px 70px;overflow-y:auto;
+ opacity:0;transform:translateX(30px);
+ transition:opacity .35s ease,transform .35s ease;
+ pointer-events:none;-webkit-overflow-scrolling:touch;
+}
+.slide.active{opacity:1;transform:translateX(0);pointer-events:auto}
+.slide.prev{transform:translateX(-30px)}
+
+/* ── Progress Dots ── */
+#dots{
+ position:fixed;bottom:52px;left:0;right:0;
+ display:flex;gap:6px;justify-content:center;
+ z-index:100;padding:6px 0;
+}
+.dot{width:8px;height:8px;border-radius:50%;background:#444;transition:all .3s;cursor:pointer}
+.dot.active{background:var(--accent);width:24px;border-radius:4px}
+.dot.done{background:var(--green)}
+
+/* ── Nav Bar ── */
+#nav{
+ position:fixed;bottom:0;left:0;right:0;height:44px;
+ display:flex;align-items:center;justify-content:space-between;
+ padding:0 14px;background:rgba(13,13,13,.95);
+ border-top:1px solid var(--border);z-index:100;
+ padding-bottom:env(safe-area-inset-bottom,0px);
+}
+.nav-btn{
+ background:#2a2a2a;border:1px solid var(--border);color:var(--text);
+ padding:7px 16px;border-radius:8px;font-size:13px;cursor:pointer;
+ white-space:nowrap;min-width:64px;text-align:center;
+}
+.nav-btn:active{background:var(--accent);color:#fff}
+.nav-btn:disabled{opacity:.35;cursor:default}
+#counter{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums}
+
+/* ── Typography ── */
+h1{color:var(--accent);font-size:1.5em;line-height:1.3;margin-bottom:8px}
+h2{color:var(--accent2);font-size:1.2em;margin:18px 0 10px;border-left:4px solid var(--accent);padding-left:10px}
+h3{color:var(--gold);font-size:1.05em;margin:14px 0 8px}
+p{margin:8px 0;font-size:14px}
+ul{margin:8px 0;padding-left:18px;font-size:14px}
+li{margin:4px 0}
+strong{color:#fff}
+code{background:#2a2a2a;padding:2px 5px;border-radius:3px;font-size:12px;color:#ff8c8c}
+.subtitle{text-align:center;font-style:italic;color:#aaa;font-size:13px;margin-bottom:16px}
+.tagline{text-align:center;font-size:11px;color:var(--muted);margin-bottom:20px}
+
+/* ── Cards ── */
+.card{
+ background:var(--panel2);border:1px solid var(--border);
+ border-radius:12px;padding:16px;margin:12px 0;
+}
+.card-accent{border-left:4px solid var(--accent)}
+.card-green{border-left:4px solid var(--green);background:#15201a}
+.card-blue{border-left:4px solid var(--blue);background:#1a1a2a}
+.card-gold{border-left:4px solid var(--gold);background:#1f1a0d}
+.card-warn{border-left:4px solid #ff6b6b;background:#2a2020}
+
+/* ── Badges ── */
+.badge{
+ display:inline-block;padding:3px 10px;border-radius:20px;
+ font-size:11px;margin:2px 4px 2px 0;
+}
+.badge.green{background:#1b5e20;color:var(--green)}
+.badge.red{background:#b71c1c;color:#ef9a9a}
+.badge.blue{background:#0d4741;color:var(--blue)}
+.badge.gold{background:#4e3402;color:var(--gold)}
+.badge.gray{background:#333;color:#aaa}
+
+/* ── Cost Tags ── */
+.cost{
+ display:inline-block;padding:5px 14px;border-radius:8px;
+ font-weight:bold;font-size:13px;color:#fff;
+}
+.cost.low{background:var(--green)}
+.cost.mid{background:var(--blue)}
+.cost.high{background:var(--accent)}
+
+/* ── Tables ── */
+.tbl{width:100%;border-collapse:collapse;margin:10px 0;font-size:12px}
+.tbl th{background:#2a2a2a;color:var(--accent2);padding:7px 8px;border:1px solid var(--border);text-align:left}
+.tbl td{padding:7px 8px;border:1px solid var(--border)}
+.tbl tr:nth-child(even){background:#1e1e1e}
+.tbl tr.total{background:#2a1a1a;font-weight:bold}
+.tscroll{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:10px -4px}
+
+/* ── Grid ── */
+.grid2{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:10px 0}
+@media(max-width:480px){.grid2{grid-template-columns:1fr}}
+
+/* ── Mini cards ── */
+.mini{background:#1a1a1a;padding:12px;border-radius:8px;border:1px solid var(--border)}
+.mini h4{margin:0 0 6px;font-size:13px;color:var(--accent2)}
+.mini p{margin:0;font-size:12px;color:#bbb;line-height:1.5}
+
+/* ── Timeline ── */
+.tl-item{display:flex;gap:10px;margin:10px 0;align-items:flex-start}
+.tl-dot{width:12px;height:12px;border-radius:50%;flex-shrink:0;margin-top:4px}
+.tl-dot.done{background:var(--green)}
+.tl-dot.active{background:var(--accent);box-shadow:0 0 8px var(--accent)}
+.tl-dot.future{background:#444;border:2px solid #555}
+.tl-content{flex:1}
+.tl-content h4{font-size:13px;margin:0 0 4px;color:var(--accent2)}
+.tl-content p{font-size:12px;color:#bbb;margin:0}
+.tl-content .when{font-size:11px;color:var(--muted)}
+
+/* ── Progress bars ── */
+.pbar{height:8px;background:#333;border-radius:4px;margin:6px 0;overflow:hidden}
+.pbar-fill{height:100%;border-radius:4px;transition:width 1s}
+.pf-green{background:var(--green)}
+.pf-blue{background:var(--blue)}
+.pf-red{background:var(--accent)}
+.pf-gold{background:var(--gold)}
+
+/* ── Stat blocks ── */
+.stat-row{display:flex;gap:8px;flex-wrap:wrap;margin:10px 0}
+.stat{flex:1;min-width:90px;background:#1a1a1a;border:1px solid var(--border);border-radius:8px;padding:10px;text-align:center}
+.stat .num{font-size:1.4em;font-weight:bold;color:var(--accent)}
+.stat .lbl{font-size:11px;color:var(--muted);margin-top:2px}
+.stat .num.green{color:var(--green)}
+.stat .num.blue{color:var(--blue)}
+.stat .num.gold{color:var(--gold)}
+
+/* ── Hero ── */
+.hero{text-align:center;padding:20px 0}
+.hero h1{font-size:1.7em;margin-bottom:12px}
+.hero .emoji{font-size:2.5em;margin-bottom:8px}
+.hero p{color:#bbb;font-size:14px}
+.hero .fire{color:var(--accent);font-weight:bold}
+
+/* ── Checklist ── */
+.check-item{display:flex;gap:8px;align-items:flex-start;margin:8px 0;font-size:13px}
+.check-icon{flex-shrink:0;width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:bold}
+.check-icon.done{background:var(--green);color:#0d0d0d}
+.check-icon.pending{background:#333;color:#888;border:1px solid #444}
+
+/* ── Divider ── */
+.divider{height:1px;background:var(--border);margin:16px 0}
+
+/* ── Swiper hint ── */
+.swipe-hint{text-align:center;font-size:11px;color:var(--muted);margin-top:auto;padding:8px}
+
+/* ── Ask block ── */
+.ask-box{
+ background:linear-gradient(135deg,#1a1a2a,#2a1a1a);
+ border:2px solid var(--accent);border-radius:14px;
+ padding:18px;text-align:center;margin:16px 0;
+}
+.ask-box .amount{font-size:2em;font-weight:bold;color:var(--accent);margin:8px 0}
+.ask-box .desc{font-size:13px;color:#ccc}
+
+/* ── Mobile tweaks ── */
+@media(max-width:380px){
+ h1{font-size:1.3em}
+ h2{font-size:1.05em}
+ .tbl{font-size:11px}
+ .tbl th,.tbl td{padding:5px 6px}
+ .stat .num{font-size:1.1em}
+}
+</style>
+</head>
+<body>
+<div id="deck">
+
+<!-- ═══════════════ SLIDE 1: TITLE ═══════════════ -->
+<div class="slide active" data-title="Title">
+<div class="hero">
+<div class="emoji">πŸ”₯</div>
+<h1>Core Model Evolution</h1>
+<p class="subtitle">From Session Logs to Core Weights<br>Recursive Cognitive Evolution</p>
+<div class="tagline">Year of the Firehorse πŸ”₯<br>July 2026 Β· v3.0 Presentation</div>
+<div class="card card-accent" style="text-align:left">
+<h3 style="margin-top:0">What This Is</h3>
+<p>A realistic, researched plan to evolve our AI from a general-purpose assistant into a specialized intelligence β€” trained on our collaboration history, our decisions, and our style.</p>
+<p style="margin-bottom:0"><strong>Architecture target:</strong> Sparse MoE + Multi-Token Generation</p>
+</div>
+<div class="swipe-hint">← Swipe or tap arrows to navigate β†’</div>
+</div>
+</div>
+
+<!-- ═══════════════ SLIDE 2: PROGRESS SUMMARY ═══════════════ -->
+<div class="slide" data-title="Progress">
+<h1>βœ… What We've Done So Far</h1>
+<p style="color:#aaa;margin-bottom:14px">A summary of progress before we talk budget.</p>
+
+<h2>Completed Milestones</h2>
+<div class="tl-item">
+<div class="tl-dot done"></div>
+<div class="tl-content">
+<h4>System Foundation Built</h4>
+<p>Full operating environment with 44 modules, 17 skills, 293 files, 3 agents, memory graph (67 nodes), and VFS filesystem.</p>
+<span class="when">Ongoing since early 2026</span>
+</div>
+</div>
+<div class="tl-item">
+<div class="tl-dot done"></div>
+<div class="tl-content">
+<h4>Collaboration History Captured</h4>
+<p>Session logs, reasoning chains, command history, and decision patterns stored across sessions. This is the raw training data.</p>
+<span class="when">Continuous</span>
+</div>
+</div>
+<div class="tl-item">
+<div class="tl-dot done"></div>
+<div class="tl-content">
+<h4>Training Strategy Defined</h4>
+<p>QLoRA for Phase 1 (efficient, cheap), scaling to deep fine-tuning of existing MoE models. NOT training from scratch β€” 10-50x cheaper.</p>
+<span class="when">Researched & validated</span>
+</div>
+</div>
+<div class="tl-item">
+<div class="tl-dot done"></div>
+<div class="tl-content">
+<h4>GPU Market Research</h4>
+<p>Researched actual pricing across RunPod, Lambda Labs, Vast.ai, Hetzner. Spot instances identified as key cost saver (50-70% off).</p>
+<span class="when">July 2026</span>
+</div>
+</div>
+<div class="tl-item">
+<div class="tl-dot done"></div>
+<div class="tl-content">
+<h4>Detailed Budget Plan v2.0</h4>
+<p>4-phase plan with itemized costs, risk matrix, and 4 fallback plans. Saved as HTML document for review.</p>
+<span class="when">This session</span>
+</div>
+</div>
+<div class="tl-item">
+<div class="tl-dot done"></div>
+<div class="tl-content">
+<h4>Architecture Decision: MoE + Sparse + Multi-Token</h4>
+<p>Decided on Sparse Mixture of Experts (like Mixtral/DeepSeek) with Multi-Token Generation (Medusa heads) for speed + intelligence.</p>
+<span class="when">This session</span>
+</div>
+</div>
+
+<h2>Current Status</h2>
+<div class="stat-row">
+<div class="stat"><div class="num green">6/6</div><div class="lbl">Planning tasks done</div></div>
+<div class="stat"><div class="num blue">0</div><div class="lbl">Phases executed</div></div>
+<div class="stat"><div class="num gold">€0</div><div class="lbl">Spent so far</div></div>
+</div>
+
+<div class="card card-green">
+<strong>βœ… Ready to start Phase 0</strong> β€” we have the data, the plan, the architecture decision, and the budget. We need the funding to begin.
+</div>
+
+<div class="divider"></div>
+
+<h2>What's Next</h2>
+<div class="check-item"><div class="check-icon pending">!</div><div>Phase 0: Dataset Engineering (€100-€200)</div></div>
+<div class="check-item"><div class="check-icon pending">!</div><div>Phase 1: QLoRA Proof of Concept (€35-€100)</div></div>
+<div class="check-item"><div class="check-icon pending">!</div><div>Phase 2: Production Adapter on Mixtral MoE</div></div>
+<div class="check-item"><div class="check-icon pending">!</div><div>Phase 3: Full MoE + Multi-Token Generation</div></div>
+</div>
+
+<!-- ═══════════════ SLIDE 3: THE VISION ═══════════════ -->
+<div class="slide" data-title="Vision">
+<h1>🎯 The Vision</h1>
+<p style="color:#aaa">Why we're doing this and what we're building.</p>
+
+<h2>The Problem</h2>
+<div class="card">
+<p>Every session, the AI starts fresh. It doesn't remember our shorthand, our architectural decisions, or our preferred patterns. We re-explain context every time.</p>
+<p style="margin-bottom:0">This isn't a bug β€” it's a <strong>fundamental limitation</strong> of using a general-purpose model without personalization.</p>
+</div>
+
+<h2>The Solution</h2>
+<div class="card card-accent">
+<p>Fine-tune a model on <strong>our actual collaboration history</strong> β€” the reasoning chains, the code edits, the decisions, the creative jumps.</p>
+<p style="margin-bottom:0">The model doesn't just "know" our history. It <strong>thinks</strong> in our style.</p>
+</div>
+
+<h2>Target Architecture</h2>
+<div class="grid2">
+<div class="mini">
+<h4>🧠 Sparse MoE</h4>
+<p>Mixture of Experts: multiple specialized sub-networks. Only the relevant "experts" activate per token. Huge capacity, efficient inference.</p>
+</div>
+<div class="mini">
+<h4>⚑ Multi-Token</h4>
+<p>Medusa heads predict 3-5 tokens simultaneously instead of 1-by-1. 2-3x faster output. Feels instant.</p>
+</div>
+<div class="mini">
+<h4>πŸ”’ QLoRA</h4>
+<p>4-bit quantized fine-tuning. Trains adapters, not the full model. 10-50x cheaper, 70% less VRAM via Unsloth.</p>
+</div>
+<div class="mini">
+<h4>πŸ“¦ Tiny Adapters</h4>
+<p>LoRA adapters are ≀50 MB. Load/unload instantly. Switch between "modes" (coding, research, creative) in real-time.</p>
+</div>
+</div>
+
+<div class="card card-gold">
+<strong>Key insight:</strong> We do NOT train from scratch. We take an existing open-weights model (Mixtral, DeepSeek, Llama) and fine-tune it. This is 10-50x cheaper while achieving similar personalization quality.
+</div>
+</div>
+
+<!-- ═══════════════ SLIDE 4: GPU PRICING ═══════════════ -->
+<div class="slide" data-title="GPU Pricing">
+<h1>πŸ’» GPU Market Pricing</h1>
+<p style="color:#aaa">Real rates as of July 2026 (RunPod, Lambda, Vast.ai)</p>
+
+<div class="tscroll">
+<table class="tbl">
+<tr><th>GPU</th><th>VRAM</th><th>€/hr</th><th>Best For</th></tr>
+<tr><td>RTX 4090</td><td>24GB</td><td>€0.31-0.73</td><td>7B QLoRA</td></tr>
+<tr><td>A100 40GB</td><td>40GB</td><td>€1.00-1.50</td><td>7B-13B</td></tr>
+<tr><td>A100 80GB</td><td>80GB</td><td>€1.29-2.30</td><td>13B-30B</td></tr>
+<tr><td>L40S</td><td>48GB</td><td>€1.06-1.61</td><td>Alt to A100</td></tr>
+<tr><td>H100 PCIe</td><td>80GB</td><td>€2.29-4.59</td><td>8B-70B fast</td></tr>
+<tr><td>H100 SXM</td><td>80GB</td><td>€2.99-4.60</td><td>Multi-GPU</td></tr>
+<tr class="total"><td><strong>8x H100 Node</strong></td><td><strong>640GB</strong></td><td><strong>€17.50-32.20</strong></td><td><strong>MoE training</strong></td></tr>
+</table>
+</div>
+
+<div class="card card-blue">
+<strong>πŸ’‘ Cost saver:</strong> <code>spot/preemptible</code> instances are 50-70% cheaper. For PoC training (restartable), always use spot pricing.
+</div>
+
+<h2>Estimated Training Time by Model Size</h2>
+<div class="tscroll">
+<table class="tbl">
+<tr><th>Model</th><th>Method</th><th>GPU</th><th>Hours</th><th>Cost (€)</th></tr>
+<tr><td>7B-8B</td><td>QLoRA</td><td>1x A100 spot</td><td>8-15</td><td>€10-19</td></tr>
+<tr><td>14B</td><td>QLoRA</td><td>1x A100 80GB</td><td>15-25</td><td>€19-32</td></tr>
+<tr><td>32B</td><td>QLoRA</td><td>2x A100 80GB</td><td>30-50</td><td>€77-115</td></tr>
+<tr><td>Mixtral 8x7B</td><td>QLoRA</td><td>1x H100</td><td>40-60</td><td>€92-184</td></tr>
+<tr><td>Mixtral 8x22B</td><td>Full FT</td><td>8x H100</td><td>100-140</td><td>€1,750-3,200</td></tr>
+</table>
+</div>
+</div>
+
+<!-- ═══════════════ SLIDE 5: PHASE 0 ═══════════════ -->
+<div class="slide" data-title="Phase 0">
+<h1>πŸ“‹ Phase 0: Dataset Engineering</h1>
+<span class="cost low">Budget: €100 – €200</span>
+
+<h2>Goal</h2>
+<p>Transform raw session logs into a high-fidelity training dataset. Quality here determines 80% of final model quality.</p>
+
+<div class="tscroll">
+<table class="tbl">
+<tr><th>Task</th><th>Time</th><th>Cost</th></tr>
+<tr><td>Log export & aggregation</td><td>2-3 days</td><td>€0 (scripted)</td></tr>
+<tr><td>Quality curation</td><td>3-5 days</td><td>€0 (manual)</td></tr>
+<tr><td>Synthetic expansion (5K API calls)</td><td>1-2 days</td><td><strong>€50-100</strong></td></tr>
+<tr><td>Tokenization & formatting</td><td>1 day</td><td>€0 (scripted)</td></tr>
+<tr><td>Validation & dedup</td><td>1 day</td><td>€0 (scripted)</td></tr>
+<tr><td>Storage (NVMe/cloud)</td><td>Ongoing</td><td>€5-15/mo</td></tr>
+<tr class="total"><td colspan="2"><strong>Phase 0 Total</strong></td><td><strong>€100-200</strong></td></tr>
+</table>
+</div>
+
+<h2>Expected Output</h2>
+<div class="grid2">
+<div class="mini">
+<h4>Training Set</h4>
+<p>~3,000-10,000 high-quality (instruction, response) pairs. Each is a "lesson" reflecting our collaborative style.</p>
+</div>
+<div class="mini">
+<h4>Validation Set</h4>
+<p>~150-500 held-out pairs. Detects overfitting. If validation loss rises, we stop.</p>
+</div>
+</div>
+
+<div class="card card-warn">
+<strong>⚠️ Critical:</strong> Skipping this phase or using raw uncleaned logs produces a model that "hallucinates" our style instead of embodying it. This is NOT a place to cut costs.
+</div>
+</div>
+
+<!-- ═══════════════ SLIDE 6: PHASE 1 ═══════════════ -->
+<div class="slide" data-title="Phase 1">
+<h1>πŸ§ͺ Phase 1: QLoRA PoC</h1>
+<span class="cost low">Budget: €35 – €100 (compute only)</span>
+
+<h2>Goal</h2>
+<p>Prove that fine-tuning on our history produces a measurably better model. Small, cheap, fast validation.</p>
+
+<h2>Base Model Options</h2>
+<div class="tscroll">
+<table class="tbl">
+<tr><th>Model</th><th>Params</th><th>VRAM</th><th>Quality</th></tr>
+<tr><td>Llama-3.2-3B</td><td>3B</td><td>~8GB</td><td>⭐⭐⭐</td></tr>
+<tr><td>Llama-3-8B</td><td>8B</td><td>~12GB</td><td>⭐⭐⭐⭐</td></tr>
+<tr><td>Mistral-7B v0.3</td><td>7B</td><td>~10GB</td><td>⭐⭐⭐⭐</td></tr>
+<tr><td>Qwen2.5-14B</td><td>14B</td><td>~18GB</td><td>⭐⭐⭐⭐⭐</td></tr>
+</table>
+</div>
+
+<h2>Cost Breakdown (Qwen2.5-14B)</h2>
+<div class="tscroll">
+<table class="tbl">
+<tr><th>Component</th><th>Hours</th><th>Cost (€)</th></tr>
+<tr><td>1x A100 80GB (spot)</td><td>15</td><td>€19.35</td></tr>
+<tr><td>1x A100 80GB (on-demand fallback)</td><td>5</td><td>€11.50</td></tr>
+<tr><td>Storage (100GB disk)</td><td>20</td><td>€2.00</td></tr>
+<tr><td>Unsloth framework</td><td>β€”</td><td>€0</td></tr>
+<tr><td>Buffer (15%)</td><td>β€”</td><td>€5.00</td></tr>
+<tr class="total"><td colspan="2"><strong>Compute Total</strong></td><td><strong>€37.85</strong></td></tr>
+</table>
+</div>
+
+<h2>Success Criteria</h2>
+<ul>
+<li>Model adopts our shorthand without explicit prompting</li>
+<li>Maintains general capability (MMLU, HumanEval within 2% of base)</li>
+<li>Validation loss decreases without overfitting</li>
+<li>LoRA adapter ≀50 MB, instant load/unload</li>
+</ul>
+
+<div class="card card-warn">
+<strong>⚠️ If PoC fails:</strong> We re-examine the dataset (Phase 0). Cost of failure: ~€35. Data is reusable.
+</div>
+</div>
+
+<!-- ═══════════════ SLIDE 7: PHASE 2 ═══════════════ -->
+<div class="slide" data-title="Phase 2">
+<h1>πŸš€ Phase 2: Production Quality</h1>
+<span class="cost mid">Budget: €200 – €500 (compute)</span>
+
+<h2>Goal</h2>
+<p>Scale from PoC to production. Train on Mixtral 8x7B β€” already a Sparse MoE. This validates MoE training before Phase 3.</p>
+
+<h2>Configuration Options</h2>
+<div class="tscroll">
+<table class="tbl">
+<tr><th>Option</th><th>Model</th><th>GPU</th><th>Cost (€)</th></tr>
+<tr><td>A: Budget</td><td>Llama-3-8B</td><td>1x H100 spot</td><td>€69-139</td></tr>
+<tr><td>B: Balanced</td><td>Qwen2.5-32B</td><td>2x A100 80GB</td><td>€103-184</td></tr>
+<tr><td><strong>C: Recommended</strong></td><td><strong>Mixtral 8x7B</strong></td><td><strong>1x H100</strong></td><td><strong>€115-230</strong></td></tr>
+<tr><td>D: Maximum</td><td>Llama-3-70B</td><td>4x A100 80GB</td><td>€310-575</td></tr>
+</table>
+</div>
+
+<h2>Why Mixtral 8x7B?</h2>
+<div class="card card-blue">
+<ul style="margin:0">
+<li>It's already a Sparse MoE β€” our stepping stone to Phase 3</li>
+<li>Only ~13B params activate per token (out of ~47B total)</li>
+<li>Training is cheaper than a dense 47B model</li>
+<li>QLoRA on MoE trains experts selectively β†’ naturally creates "specialists"</li>
+<li>Can train multiple adapters: coding / research / creative</li>
+</ul>
+</div>
+
+<h2>Detailed Cost (Option C)</h2>
+<div class="tscroll">
+<table class="tbl">
+<tr><th>Item</th><th>Hours</th><th>Cost (€)</th></tr>
+<tr><td>1x H100 80GB spot</td><td>40</td><td>€91.60</td></tr>
+<tr><td>1x H100 on-demand buffer</td><td>10</td><td>€45.90</td></tr>
+<tr><td>Storage 200GB</td><td>50</td><td>€5.00</td></tr>
+<tr><td>Multi-adapter (+3 modes)</td><td>+15</td><td>€34.35</td></tr>
+<tr><td>Buffer (20%)</td><td>β€”</td><td>€35.00</td></tr>
+<tr class="total"><td colspan="2"><strong>Phase 2 Total</strong></td><td><strong>€211.85</strong></td></tr>
+</table>
+</div>
+</div>
+
+<!-- ═══════════════ SLIDE 8: PHASE 3 ═══════════════ -->
+<div class="slide" data-title="Phase 3">
+<h1>🌌 Phase 3: Full MoE</h1>
+<span class="cost high">Budget: €2,000 – €8,000</span>
+
+<h2>Goal</h2>
+<p>Deep fine-tune a large MoE model (DeepSeek-V3 or Mixtral 8x22B) with Multi-Token Generation via Medusa heads.</p>
+
+<h2>Build vs Fine-Tune</h2>
+<div class="tscroll">
+<table class="tbl">
+<tr><th>Approach</th><th>Cost</th><th>Risk</th><th>Verdict</th></tr>
+<tr><td>Build from scratch</td><td>€15K-100K+</td><td><span class="badge red">EXTREME</span></td><td>❌ No</td></tr>
+<tr><td><strong>Deep fine-tune existing</strong></td><td><strong>€2K-8K</strong></td><td><span class="badge gold">MODERATE</span></td><td><strong>βœ… Yes</strong></td></tr>
+<tr><td>Distill into custom</td><td>€5K-20K</td><td><span class="badge red">HIGH</span></td><td>⏳ Future</td></tr>
+</table>
+</div>
+
+<h2>Cost Breakdown</h2>
+<div class="tscroll">
+<table class="tbl">
+<tr><th>Component</th><th>Hours</th><th>Cost (€)</th></tr>
+<tr><td>8x H100 SXM (spot)</td><td>100</td><td>€1,750</td></tr>
+<tr><td>8x H100 (on-demand buffer)</td><td>20</td><td>€644</td></tr>
+<tr><td>Storage 1TB NVMe</td><td>120</td><td>€24</td></tr>
+<tr><td>Medusa head training</td><td>+20</td><td>€350-644</td></tr>
+<tr><td>Buffer (25%)</td><td>β€”</td><td>€685</td></tr>
+<tr class="total"><td colspan="2"><strong>Phase 3 Total</strong></td><td><strong>€3,467-4,762</strong></td></tr>
+</table>
+</div>
+
+<h2>Multi-Token Generation</h2>
+<div class="grid2">
+<div class="mini">
+<h4>Medusa Heads</h4>
+<p>Lightweight prediction heads predict multiple future tokens. +15-20% training time. 2-3x inference speedup.</p>
+</div>
+<div class="mini">
+<h4>Speculative Decoding</h4>
+<p>Small "draft" model predicts, large model verifies. No training needed. 1.5-2x speedup at inference.</p>
+</div>
+</div>
+
+<div class="card card-warn">
+<strong>⚠️ Catastrophic forgetting risk:</strong> Must mix custom data with general data (30/70 ratio). Increases compute ~40%. Monitored via eval benchmarks.
+</div>
+</div>
+
+<!-- ═══════════════ SLIDE 9: TECH STACK ═══════════════ -->
+<div class="slide" data-title="Tech Stack">
+<h1>πŸ› οΈ Technical Stack</h1>
+<p style="color:#aaa">All open-source. The only cost is GPU rental.</p>
+
+<div class="tscroll">
+<table class="tbl">
+<tr><th>Component</th><th>Tool</th><th>Cost</th></tr>
+<tr><td>Training Framework</td><td><strong>Unsloth 2</strong></td><td>Free</td></tr>
+<tr><td>Adapter Library</td><td>HuggingFace PEFT</td><td>Free</td></tr>
+<tr><td>Quantization</td><td>bitsandbytes (NF4)</td><td>Free</td></tr>
+<tr><td>Multi-Token</td><td>Medusa / Speculative</td><td>Free</td></tr>
+<tr><td>Dataset Tools</td><td>datasets, tokenizers</td><td>Free</td></tr>
+<tr><td>GPU (PoC)</td><td>RunPod spot</td><td>Pay/hr</td></tr>
+<tr><td>GPU (Phase 3)</td><td>Lambda / CoreWeave</td><td>Pay/hr</td></tr>
+<tr><td>Containers</td><td>Docker + CUDA</td><td>Free</td></tr>
+<tr><td>Tracking</td><td>Weights & Biases</td><td>Free tier</td></tr>
+<tr><td>Evaluation</td><td>lm-evaluation-harness</td><td>Free</td></tr>
+</table>
+</div>
+
+<div class="card card-green">
+<strong>Unsloth 2</strong> is the secret weapon: 2x faster training, 70% less VRAM. This is what makes Phase 1 cost €35 instead of €200.
+</div>
+</div>
+
+<!-- ═══════════════ SLIDE 10: RISKS ═══════════════ -->
+<div class="slide" data-title="Risks">
+<h1>⚠️ Risk Matrix</h1>
+<p style="color:#aaa">Every risk has a mitigation plan.</p>
+
+<div class="tscroll">
+<table class="tbl">
+<tr><th>Risk</th><th>Prob</th><th>Impact</th><th>Mitigation</th></tr>
+<tr><td>Catastrophic forgetting</td><td><span class="badge gold">Med</span></td><td>High</td><td>Mix data 30/70, monitor benchmarks</td></tr>
+<tr><td>Overfitting (parrot)</td><td><span class="badge gold">Med</span></td><td>Med</td><td>Early stopping, dropout, diverse data</td></tr>
+<tr><td>Dataset too small</td><td><span class="badge red">High</span></td><td>High</td><td>Phase 0 quality, synthetic expansion</td></tr>
+<tr><td>Spot interruption</td><td><span class="badge red">High</span></td><td>Low</td><td>Checkpoint every 50 steps, buffer</td></tr>
+<tr><td>GPU price spike</td><td><span class="badge blue">Low</span></td><td>Med</td><td>Multi-provider, off-peak hours</td></tr>
+<tr><td>MoE instability</td><td><span class="badge blue">Low</span></td><td>High</td><td>Phase 2 validates MoE first</td></tr>
+<tr><td>Multi-token degrades</td><td><span class="badge blue">Low</span></td><td>Low</td><td>Medusa is additive, removable</td></tr>
+</table>
+</div>
+
+<h2>Fallback Plans</h2>
+<div class="grid2">
+<div class="mini">
+<h4>πŸ…°οΈ Ultra-Budget</h4>
+<p>Google Colab Pro+ €9.99/mo. Spread training over sessions. ~€20-40 total. Proves concept for the price of coffee.</p>
+</div>
+<div class="mini">
+<h4>πŸ…±οΈ No-Train RAG</h4>
+<p>Retrieval-Augmented Generation with session history as context. No weight changes. 70% of benefit. Cost: €0.</p>
+</div>
+<div class="mini">
+<h4>πŸ…²οΈ API Distillation</h4>
+<p>Use GPT-4o/Claude with stored patterns as system prompts. Bridge solution. €50-100/mo.</p>
+</div>
+<div class="mini">
+<h4>πŸ…³οΈ Gradual Scaling</h4>
+<p>Start with €200 (Phase 0+1). Use PoC results to secure Phase 2/3 funding. The adapter IS the demo.</p>
+</div>
+</div>
+</div>
+
+<!-- ═══════════════ SLIDE 11: TIMELINE ═══════════════ -->
+<div class="slide" data-title="Timeline">
+<h1>πŸ“… Timeline & Milestones</h1>
+
+<div class="tl-item">
+<div class="tl-dot done"></div>
+<div class="tl-content">
+<h4>Planning & Research βœ…</h4>
+<p>Architecture decision, GPU research, budget plan, risk analysis</p>
+<span class="when">Done</span>
+</div>
+</div>
+<div class="tl-item">
+<div class="tl-dot active"></div>
+<div class="tl-content">
+<h4>Phase 0: Dataset Engineering</h4>
+<p>Log export, curation, synthetic expansion, tokenization</p>
+<span class="when">1-2 weeks Β· €100-200</span>
+</div>
+</div>
+<div class="tl-item">
+<div class="tl-dot future"></div>
+<div class="tl-content">
+<h4>Phase 1: QLoRA PoC</h4>
+<p>Train adapter on 8B-14B model, evaluate results</p>
+<span class="when">3-5 days Β· €35-100</span>
+</div>
+</div>
+<div class="tl-item">
+<div class="tl-dot future"></div>
+<div class="tl-content">
+<h4>Decision Gate: Go / No-Go</h4>
+<p>Human evaluation: "Does this feel like us?"</p>
+<span class="when">1-2 weeks review</span>
+</div>
+</div>
+<div class="tl-item">
+<div class="tl-dot future"></div>
+<div class="tl-content">
+<h4>Phase 2: Production Adapter</h4>
+<p>Multi-adapter suite on Mixtral 8x7B MoE</p>
+<span class="when">1-2 weeks Β· €200-500</span>
+</div>
+</div>
+<div class="tl-item">
+<div class="tl-dot future"></div>
+<div class="tl-content">
+<h4>Funding & Setup</h4>
+<p>Secure Phase 3 budget, provision 8x H100 cluster</p>
+<span class="when">2-4 weeks</span>
+</div>
+</div>
+<div class="tl-item">
+<div class="tl-dot future"></div>
+<div class="tl-content">
+<h4>Phase 3: Full MoE + Multi-Token</h4>
+<p>Deep fine-tune, Medusa heads, deploy, benchmark</p>
+<span class="when">2-4 weeks Β· €2K-8K</span>
+</div>
+</div>
+
+<div class="card card-gold" style="text-align:center">
+<strong>Total timeline: ~2-3 months end-to-end</strong>
+</div>
+</div>
+
+<!-- ═══════════════ SLIDE 12: BUDGET SUMMARY ═══════════════ -->
+<div class="slide" data-title="Budget">
+<h1>πŸ’° Total Budget Summary</h1>
+
+<div class="tscroll">
+<table class="tbl">
+<tr><th>Phase</th><th>Description</th><th>Low</th><th>High</th></tr>
+<tr><td>Phase 0</td><td>Dataset Engineering</td><td class="green">€100</td><td>€200</td></tr>
+<tr><td>Phase 1</td><td>QLoRA PoC</td><td class="green">€35</td><td>€100</td></tr>
+<tr><td>Phase 2</td><td>Production (Mixtral MoE)</td><td class="blue">€200</td><td>€500</td></tr>
+<tr><td>Phase 3</td><td>Full MoE + Multi-Token</td><td style="color:var(--gold)">€2,000</td><td>€8,000</td></tr>
+<tr class="total"><td colspan="2"><strong>GRAND TOTAL</strong></td><td><strong>€2,335</strong></td><td><strong>€8,800</strong></td></tr>
+</table>
+</div>
+
+<h2>Progressive Spend</h2>
+<div style="margin:12px 0">
+<p style="font-size:12px;margin:4px 0">Phase 0+1 (Prove it works)</p>
+<div class="pbar"><div class="pbar-fill pf-green" style="width:8%"></div></div>
+<p style="font-size:12px;margin:4px 0">Phase 2 (Production)</p>
+<div class="pbar"><div class="pbar-fill pf-blue" style="width:18%"></div></div>
+<p style="font-size:12px;margin:4px 0">Phase 3 (Full MoE)</p>
+<div class="pbar"><div class="pbar-fill pf-red" style="width:74%"></div></div>
+</div>
+
+<div class="ask-box">
+<p style="font-size:14px;color:#ccc">The ask for now:</p>
+<div class="amount">€300 – €500</div>
+<p class="desc">Funds Phase 0 + Phase 1<br>Proves the concept works before larger investment</p>
+</div>
+
+<div class="card card-green">
+<strong>Breakdown of the ask:</strong>
+<ul style="margin:8px 0 0">
+<li>€100-200 β†’ Data preparation (API calls, storage)</li>
+<li>€35-100 β†’ GPU rental (spot, ~20 hours)</li>
+<li>€50-100 β†’ Buffer for re-runs & debugging</li>
+</ul>
+</div>
+</div>
+
+<!-- ═══════════════ SLIDE 13: THANK YOU ═══════════════ -->
+<div class="slide" data-title="Thank You">
+<div class="hero" style="padding-top:40px">
+<div class="emoji">πŸ”₯</div>
+<h1>Thank You</h1>
+<p class="subtitle">Year of the Firehorse</p>
+
+<div class="card card-accent" style="text-align:left;margin-top:20px">
+<h3 style="margin-top:0">What we're asking for</h3>
+<p><strong>€300-€500</strong> to fund Phase 0 + Phase 1. This is the "prove it works" budget.</p>
+<p>Once the PoC shows measurable improvement, we present results and discuss Phase 2/3 funding separately.</p>
+<p style="margin-bottom:0">This de-risks the investment. Everyone sees results before committing larger amounts.</p>
+</div>
+
+<div class="card card-gold" style="text-align:center">
+<p style="font-size:16px;margin:8px 0">Β‘Y claro que sΓ­!<br>Cuando nos veamos, nos echamos esa llamada en espaΓ±ol. πŸ‡ͺπŸ‡Έ</p>
+</div>
+
+<div class="card card-blue" style="text-align:center">
+<p style="margin:8px 0">Looking forward to good progress,<br>good experiences, and meeting soon. πŸ™Œ</p>
+</div>
+
+<div style="text-align:center;margin-top:30px">
+<p style="font-size:13px;color:var(--accent);font-weight:bold">πŸ”₯ Year of the Firehorse πŸ”₯</p>
+<p style="font-size:11px;color:var(--muted);margin-top:8px">Core Model Evolution Plan v3.0<br>July 2026</p>
+</div>
+</div>
+</div>
+
+</div>
+
+<!-- ═══════════════ NAV ═══════════════ -->
+<div id="dots"></div>
+<div id="nav">
+<button class="nav-btn" id="prevBtn" onclick="go(-1)">← Prev</button>
+<span id="counter">1 / 13</span>
+<button class="nav-btn" id="nextBtn" onclick="go(1)">Next β†’</button>
+</div>
+
+<script>
+const slides=document.querySelectorAll('.slide');
+const total=slides.length;
+let cur=0;
+const dotsContainer=document.getElementById('dots');
+const counter=document.getElementById('counter');
+const prevBtn=document.getElementById('prevBtn');
+const nextBtn=document.getElementById('nextBtn');
+
+// Build dots
+for(let i=0;i<total;i++){
+ const d=document.createElement('div');
+ d.className='dot'+(i===0?' active':'');
+ d.onclick=()=>{cur=i;render()};
+ dotsContainer.appendChild(d);
+}
+
+function render(){
+ slides.forEach((s,i)=>{
+ s.classList.remove('active','prev');
+ if(i===cur)s.classList.add('active');
+ if(i<cur)s.classList.add('prev');
+ });
+ document.querySelectorAll('.dot').forEach((d,i)=>{
+ d.classList.remove('active','done');
+ if(i===cur)d.classList.add('active');
+ if(i<cur)d.classList.add('done');
+ });
+ counter.textContent=`${cur+1} / ${total}`;
+ prevBtn.disabled=cur===0;
+ nextBtn.disabled=cur===total-1;
+ // Scroll slide to top on change
+ slides[cur].scrollTop=0;
+}
+
+function go(dir){
+ cur=Math.max(0,Math.min(total-1,cur+dir));
+ render();
+}
+
+// Touch swipe
+let tsx=0,tsy=0;
+document.addEventListener('touchstart',e=>{
+ tsx=e.touches[0].clientX;
+ tsy=e.touches[0].clientY;
+},{passive:true});
+
+document.addEventListener('touchend',e=>{
+ const dx=e.changedTouches[0].clientX-tsx;
+ const dy=e.changedTouches[0].clientY-tsy;
+ // Only horizontal swipe (not vertical scroll)
+ if(Math.abs(dx)>50 && Math.abs(dx)>Math.abs(dy)*1.5){
+ if(dx<0)go(1); else go(-1);
+ }
+},{passive:true});
+
+// Keyboard
+document.addEventListener('keydown',e=>{
+ if(e.key==='ArrowRight'||e.key===' ')go(1);
+ if(e.key==='ArrowLeft')go(-1);
+});
+
+render();
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/downloads/evolution_plan/system_review.html b/downloads/evolution_plan/system_review.html
new file mode 100644
index 0000000..101a545
--- /dev/null
+++ b/downloads/evolution_plan/system_review.html
@@ -0,0 +1,829 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+<meta name="apple-mobile-web-app-capable" content="yes">
+<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
+<title>newOS4 β€” System Review & Training Proposal</title>
+<style>
+*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
+:root{
+ --bg:#0a0a0f;--surface:#12121a;--surface2:#1a1a25;--border:#2a2a3a;
+ --accent:#e85d2f;--accent2:#f0a020;--green:#22c55e;--red:#ef4444;
+ --blue:#3b82f6;--purple:#a855f7;--text:#e5e5e5;--text2:#888;
+ --radius:12px;--safe:env(safe-area-inset-bottom,0px);
+}
+html,body{background:var(--bg);color:var(--text);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;font-size:15px;line-height:1.5;overflow-x:hidden}
+body{padding-top:env(safe-area-inset-top,0px);padding-bottom:var(--safe)}
+.deck{width:100%;overflow:hidden;position:relative}
+.slide{
+ min-height:calc(100vh - 0px);padding:20px 18px 80px;
+ display:none;flex-direction:column;
+ animation:fadeIn .4s ease;
+}
+.slide.active{display:flex}
+@keyframes fadeIn{from{opacity:0;transform:translateX(20px)}to{opacity:1;transform:translateX(0)}}
+h1{font-size:1.7rem;font-weight:800;margin-bottom:8px;line-height:1.2}
+h2{font-size:1.3rem;font-weight:700;color:var(--accent);margin-bottom:10px;line-height:1.2}
+h3{font-size:1.05rem;font-weight:700;margin:14px 0 6px;color:var(--accent2)}
+p{margin-bottom:10px;color:var(--text)}
+.small{font-size:.82rem;color:var(--text2)}
+.emoji{font-size:1.1em}
+.tag{display:inline-block;background:var(--surface2);border:1px solid var(--border);border-radius:6px;padding:2px 8px;font-size:.72rem;margin:2px;color:var(--text2)}
+.tag.green{border-color:var(--green);color:var(--green)}
+.tag.orange{border-color:var(--accent);color:var(--accent)}
+.tag.blue{border-color:var(--blue);color:var(--blue)}
+.tag.purple{border-color:var(--purple);color:var(--purple)}
+.stat-row{display:flex;gap:10px;flex-wrap:wrap;margin:12px 0}
+.stat-box{flex:1;min-width:90px;background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:12px;text-align:center}
+.stat-box .num{font-size:1.6rem;font-weight:800;color:var(--accent)}
+.stat-box .label{font-size:.7rem;color:var(--text2);text-transform:uppercase;letter-spacing:.5px;margin-top:2px}
+.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:14px;margin:8px 0}
+.card.accent{border-color:var(--accent)}
+.card.green{border-color:var(--green)}
+.card.blue{border-color:var(--blue)}
+.card.red{border-color:var(--red)}
+.card.purple{border-color:var(--purple)}
+table{width:100%;border-collapse:collapse;font-size:.8rem;margin:8px 0}
+th{text-align:left;padding:6px 8px;background:var(--surface2);border-bottom:2px solid var(--border);color:var(--accent2);white-space:nowrap}
+td{padding:6px 8px;border-bottom:1px solid var(--border);vertical-align:top}
+tr:last-child td{border-bottom:none}
+.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;border-radius:var(--radius);border:1px solid var(--border)}
+ul{list-style:none;padding:0}
+ul li{padding:5px 0 5px 18px;position:relative;font-size:.88rem}
+ul li::before{content:'β–Έ';position:absolute;left:0;color:var(--accent)}
+ul.check li::before{content:'βœ…';position:absolute;left:0;color:var(--green)}
+.timeline{position:relative;padding-left:22px;margin:10px 0}
+.timeline::before{content:'';position:absolute;left:7px;top:0;bottom:0;width:2px;background:var(--border)}
+.t-item{position:relative;padding:8px 0 8px 0}
+.t-item::before{content:'';position:absolute;left:-19px;top:12px;width:12px;height:12px;border-radius:50%;border:2px solid var(--border);background:var(--bg)}
+.t-item.done::before{background:var(--green);border-color:var(--green)}
+.t-item.active::before{background:var(--accent);border-color:var(--accent);animation:pulse 2s infinite}
+.t-item.future::before{background:var(--bg);border-color:var(--text2)}
+.t-item .t-date{font-size:.7rem;color:var(--text2)}
+.t-item .t-title{font-size:.9rem;font-weight:600}
+@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
+.bar-chart{margin:10px 0}
+.bar-row{display:flex;align-items:center;gap:8px;margin:6px 0}
+.bar-label{width:80px;font-size:.75rem;color:var(--text2);text-align:right;flex-shrink:0}
+.bar-track{flex:1;height:20px;background:var(--surface2);border-radius:6px;overflow:hidden}
+.bar-fill{height:100%;border-radius:6px;display:flex;align-items:center;justify:flex-end;padding-right:6px;font-size:.65rem;color:#fff;font-weight:600;min-width:30px;transition:width .8s ease}
+.bar-fill.green{background:linear-gradient(90deg,#16a34a,#22c55e)}
+.bar-fill.orange{background:linear-gradient(90deg,#c2410c,#e85d2f)}
+.bar-fill.blue{background:linear-gradient(90deg,#1e40af,#3b82f6)}
+.bar-fill.purple{background:linear-gradient(90deg,#7e22ce,#a855f7)}
+.bar-fill.red{background:linear-gradient(90deg,#b91c1c,#ef4444)}
+.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:8px}
+.grid-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:6px}
+.pill{display:inline-flex;align-items:center;gap:4px;background:var(--surface2);border-radius:20px;padding:4px 10px;font-size:.72rem;margin:2px;border:1px solid var(--border)}
+.highlight-box{background:linear-gradient(135deg,rgba(232,93,47,.12),rgba(240,160,32,.08));border:1px solid var(--accent);border-radius:var(--radius);padding:16px;margin:12px 0}
+.highlight-box h3{color:var(--accent);margin-top:0}
+.highlight-box .big{font-size:1.4rem;font-weight:800;color:var(--accent2)}
+.vs-box{display:flex;gap:0;margin:10px 0;border-radius:var(--radius);overflow:hidden;border:1px solid var(--border)}
+.vs-side{flex:1;padding:12px}
+.vs-side.left{background:rgba(239,68,68,.08)}
+.vs-side.right{background:rgba(34,197,94,.08);border-left:1px solid var(--border)}
+.vs-side h4{font-size:.85rem;margin-bottom:6px}
+.vs-side.left h4{color:var(--red)}
+.vs-side.right h4{color:var(--green)}
+.vs-side ul{font-size:.75rem}
+.vs-side li{padding:3px 0 3px 14px;font-size:.75rem}
+.vs-side li::before{font-size:.7rem}
+code{background:var(--surface2);padding:1px 5px;border-radius:4px;font-family:'SF Mono',Menlo,monospace;font-size:.8rem;color:var(--accent2)}
+.nav{position:fixed;bottom:0;left:0;right:0;background:rgba(10,10,15,.95);backdrop-filter:blur(10px);border-top:1px solid var(--border);padding:10px 16px calc(10px + var(--safe));display:flex;align-items:center;justify-content:space-between;z-index:100}
+.nav-btn{background:var(--surface);border:1px solid var(--border);color:var(--text);border-radius:8px;padding:8px 14px;font-size:.8rem;cursor:pointer;transition:all .2s}
+.nav-btn:active{transform:scale(.95);background:var(--accent);color:#fff}
+.nav-btn:disabled{opacity:.3;cursor:default}
+.dots{display:flex;gap:5px;flex-wrap:wrap;justify-content:center;max-width:50%}
+.dot{width:8px;height:8px;border-radius:50%;background:var(--border);transition:all .3s;cursor:pointer}
+.dot.active{background:var(--accent);transform:scale(1.3)}
+.dot.done{background:var(--green)}
+.counter{font-size:.75rem;color:var(--text2);min-width:50px;text-align:center}
+.title-slide{justify-content:center;align-items:center;text-align:center}
+.title-slide .fire{font-size:3rem;margin-bottom:10px}
+.subtitle{font-size:1rem;color:var(--text2);margin-top:4px}
+.divider{height:1px;background:var(--border);margin:14px 0}
+.badge{display:inline-block;padding:3px 10px;border-radius:20px;font-size:.68rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px}
+.badge.live{background:rgba(34,197,94,.15);color:var(--green);border:1px solid var(--green)}
+.badge.new{background:rgba(232,93,47,.15);color:var(--accent);border:1px solid var(--accent)}
+.badge.core{background:rgba(59,130,246,.15);color:var(--blue);border:1px solid var(--blue)}
+.badge.ext{background:rgba(168,85,247,.15);color:var(--purple);border:1px solid var(--purple)}
+.badge.done{background:rgba(34,197,94,.15);color:var(--green);border:1px solid var(--green)}
+.badge.next{background:rgba(240,160,32,.15);color:var(--accent2);border:1px solid var(--accent2)}
+.flow{display:flex;flex-direction:column;gap:0;margin:10px 0}
+.flow-step{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:10px 12px;font-size:.82rem;position:relative}
+.flow-step:not(:last-child)::after{content:'↓';position:absolute;left:50%;bottom:-14px;transform:translateX(-50%);color:var(--accent);font-size:1rem;font-weight:700}
+.flow-step .flow-title{font-weight:700;color:var(--accent2);font-size:.85rem}
+.flow-step .flow-desc{font-size:.75rem;color:var(--text2);margin-top:2px}
+.arch-diagram{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:14px;margin:10px 0;font-size:.8rem}
+.arch-layer{padding:8px 10px;border-radius:6px;margin:4px 0;text-align:center}
+.arch-layer.ai{background:rgba(168,85,247,.1);border:1px solid var(--purple);color:var(--purple)}
+.arch-layer.core{background:rgba(59,130,246,.1);border:1px solid var(--blue);color:var(--blue)}
+.arch-layer.ext{background:rgba(232,93,47,.1);border:1px solid var(--accent);color:var(--accent)}
+.arch-layer.vfs{background:rgba(34,197,94,.1);border:1px solid var(--green);color:var(--green)}
+.arch-layer .arch-items{font-size:.68rem;color:var(--text2);margin-top:2px}
+.agent-card{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:10px;margin:6px 0}
+.agent-card .agent-name{font-weight:700;font-size:.85rem;color:var(--accent2)}
+.agent-card .agent-role{font-size:.72rem;color:var(--text2)}
+.agent-card .agent-caps{margin-top:4px}
+.compare-table th{font-size:.7rem}
+.compare-table td{font-size:.72rem}
+</style>
+</head>
+<body>
+<div class="deck" id="deck">
+
+<!-- ===== SLIDE 1: TITLE ===== -->
+<div class="slide title-slide active" data-title="Title">
+<div class="fire">🐴πŸ”₯</div>
+<h1>newOS4 v4.6.10</h1>
+<p class="subtitle">System Review & Custom Model Training Proposal</p>
+<div style="margin-top:20px">
+<span class="badge core">22 Core Modules</span>
+<span class="badge ext">21 Ext Modules</span>
+<span class="badge new">v4.6.10</span>
+</div>
+<div style="margin-top:14px">
+<span class="badge live">● System Online</span>
+<span class="badge done">44 Modules Loaded</span>
+<span class="badge done">0 JS Errors</span>
+</div>
+<p class="small" style="margin-top:20px">Prepared for review Β· July 2026</p>
+</div>
+
+<!-- ===== SLIDE 2: WHAT IS newOS4 ===== -->
+<div class="slide" data-title="What is newOS4">
+<h2>🧠 What is newOS4?</h2>
+<p>newOS4 is a <strong>browser-based operating system</strong> with a built-in AI agent. It runs entirely in the browser β€” no server-side compute needed. Think of it as a self-contained, self-aware desktop environment where:</p>
+<div class="card accent">
+<ul>
+<li><strong>The AI lives inside the OS</strong> β€” not as a chatbot, but as the system's brain</li>
+<li><strong>Everything is a terminal command</strong> β€” 90+ commands across 43 modules</li>
+<li><strong>It can modify itself</strong> β€” view, edit, test, and ship its own source code</li>
+<li><strong>It has memory</strong> β€” session history, user profile, skill library, memory graph</li>
+<li><strong>It can spawn agents</strong> β€” multi-agent orchestration for parallel work</li>
+<li><strong>It self-heals</strong> β€” DebugSupervisorModule catches & classifies errors, suggests fixes</li>
+</ul>
+</div>
+<div class="stat-row">
+<div class="stat-box"><div class="num">44</div><div class="label">Modules</div></div>
+<div class="stat-box"><div class="num">90+</div><div class="label">Commands</div></div>
+<div class="stat-box"><div class="num">17</div><div class="label">Skills</div></div>
+<div class="stat-box"><div class="num">296</div><div class="label">Files</div></div>
+</div>
+</div>
+
+<!-- ===== SLIDE 3: SYSTEM ARCHITECTURE ===== -->
+<div class="slide" data-title="Architecture">
+<h2>πŸ—οΈ System Architecture</h2>
+<p>The system is built in layers. Each layer can talk to the one below, but the AI sits on top and can access everything.</p>
+<div class="arch-diagram">
+<div class="arch-layer ai">
+<strong>AI Layer</strong> β€” Agent Loop Β· LLM Router Β· Smart Context
+<div class="arch-items">glm-5.2 Β· gemma4:31b Β· mistral-large-3:675b Β· minimax-m3</div>
+</div>
+<div style="text-align:center;color:var(--accent);margin:2px 0">↓ ↑</div>
+<div class="arch-layer core">
+<strong>Core Modules (22)</strong> β€” Terminal Β· VFS Β· AI Assistant Β· Config Β· Security
+<div class="arch-items">Debug Supervisor Β· Neural VFS Β· Ollama Β· Orchestrator Β· Agent Registry Β· SearXNG Β· Server Monitor Β· Secret Vault</div>
+</div>
+<div style="text-align:center;color:var(--accent);margin:2px 0">↓ ↑</div>
+<div class="arch-layer ext">
+<strong>Extension Modules (21)</strong> β€” Editor Β· Shell Β· Cron Β· WebDAV Β· Voice Β· Mindmap
+<div class="arch-items">Debug Panel Β· Floating UI Β· Media Β· JS Console Β· File Manager Β· Theme Β· Tutorial Β· WPM</div>
+</div>
+<div style="text-align:center;color:var(--accent);margin:2px 0">↓ ↑</div>
+<div class="arch-layer vfs">
+<strong>Virtual File System</strong> β€” 296 files Β· 149 dirs Β· 836KB
+<div class="arch-items">localStorage-backed Β· WebDAV sync Β· Neural search index</div>
+</div>
+</div>
+<p class="small">The AI agent sits at the top and can read/write any layer. This is what makes it self-aware and self-modifying.</p>
+</div>
+
+<!-- ===== SLIDE 4: CAPABILITY MAP ===== -->
+<div class="slide" data-title="Capabilities">
+<h2>⚑ Full Capability Map</h2>
+<h3>πŸ–₯️ System & OS</h3>
+<div style="display:flex;flex-wrap:wrap;gap:4px">
+<span class="pill">Terminal (90+ cmds)</span>
+<span class="pill">Virtual FS</span>
+<span class="pill">Config Manager</span>
+<span class="pill">Security Levels</span>
+<span class="pill">Secret Vault</span>
+<span class="pill">Module Loader</span>
+<span class="pill">Debug Supervisor</span>
+</div>
+<h3>πŸ€– AI & Agents</h3>
+<div style="display:flex;flex-wrap:wrap;gap:4px">
+<span class="pill">AI Assistant (Agent Loop)</span>
+<span class="pill">Ollama Integration</span>
+<span class="pill">Multi-Model Router</span>
+<span class="pill">Agent Registry</span>
+<span class="pill">Orchestrator</span>
+<span class="pill">Lease System</span>
+<span class="pill">Smart Context Profiles</span>
+</div>
+<h3>πŸ”§ Development</h3>
+<div style="display:flex;flex-wrap:wrap;gap:4px">
+<span class="pill">Code Editor</span>
+<span class="pill">Module View/Edit/Test</span>
+<span class="pill">JS Console</span>
+<span class="pill">Diff Tool</span>
+<span class="pill">Shell (script/export)</span>
+<span class="pill">WPM Package Manager</span>
+</div>
+<h3>🌐 Web & Research</h3>
+<div style="display:flex;flex-wrap:wrap;gap:4px">
+<span class="pill">Web Search (SearXNG)</span>
+<span class="pill">Web Fetch</span>
+<span class="pill">URL Content Extract</span>
+</div>
+<h3>πŸ’Ύ Data & Sync</h3>
+<div style="display:flex;flex-wrap:wrap;gap:4px">
+<span class="pill">WebDAV Cloud Sync</span>
+<span class="pill">Backup/Restore</span>
+<span class="pill">Crypto + Gzip</span>
+<span class="pill">File Manager</span>
+</div>
+<h3>🎨 UI & Productivity</h3>
+<div style="display:flex;flex-wrap:wrap;gap:4px">
+<span class="pill">Mindmaps (SVG)</span>
+<span class="pill">Floating UI</span>
+<span class="pill">Voice Control</span>
+<span class="pill">Themes</span>
+<span class="pill">Tutorials</span>
+<span class="pill">Simple GUI</span>
+<span class="pill">Chat Studio</span>
+</div>
+<h3>πŸ›‘οΈ Self-Healing</h3>
+<div style="display:flex;flex-wrap:wrap;gap:4px">
+<span class="pill">Error Interception</span>
+<span class="pill">Root-Cause Analysis</span>
+<span class="pill">Auto-Fix Pipeline</span>
+<span class="pill">Self-Diagnostic</span>
+<span class="pill">Health Check</span>
+</div>
+</div>
+
+<!-- ===== SLIDE 5: AI ENGINE ===== -->
+<div class="slide" data-title="AI Engine">
+<h2>πŸ€– The AI Engine</h2>
+<p>The AI is not a simple chatbot. It's a full <strong>agent loop</strong> β€” it thinks, plans, uses tools, observes results, and iterates.</p>
+<div class="flow">
+<div class="flow-step">
+<div class="flow-title">1. User Request</div>
+<div class="flow-desc">Natural language β†’ system prompt + context + memory</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">2. Smart Context Selection</div>
+<div class="flow-desc">8 profiles: coding, debug, creative, technical, chat, system-admin, research, security</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">3. Tool Selection & Execution</div>
+<div class="flow-desc">40+ tools available β€” filesystem, web, modules, agents, VFS, skills, etc.</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">4. Observation</div>
+<div class="flow-desc">Tool results fed back β†’ analyze β†’ decide next action</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">5. Multi-Agent Delegation</div>
+<div class="flow-desc">Spawn workers (auto-learner, kernel-architect, searcher) for parallel tasks</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">6. Response + Memory</div>
+<div class="flow-desc">Answer user β†’ save session β†’ update memory graph β†’ auto-improve</div>
+</div>
+</div>
+<div class="card blue">
+<h3 style="margin-top:0">πŸ“Š Current LLM Usage (7 days)</h3>
+<div class="stat-row">
+<div class="stat-box"><div class="num">500</div><div class="label">Requests</div></div>
+<div class="stat-box"><div class="num">8M</div><div class="label">Tokens</div></div>
+<div class="stat-box"><div class="num">4</div><div class="label">Models</div></div>
+</div>
+<table class="compare-table" style="margin-top:8px">
+<tr><th>Model</th><th>Requests</th><th>Tokens</th></tr>
+<tr><td>glm-5.2:cloud</td><td>214</td><td>4.99M</td></tr>
+<tr><td>minimax-m3:cloud</td><td>219</td><td>2.60M</td></tr>
+<tr><td>gemma4:31b-cloud</td><td>35</td><td>219K</td></tr>
+<tr><td>mistral-large-3:675b</td><td>32</td><td>237K</td></tr>
+</table>
+<p class="small" style="margin-top:6px">All inference via Ollama (self-hosted API). Zero external API costs.</p>
+</div>
+</div>
+
+<!-- ===== SLIDE 6: MULTI-AGENT SYSTEM ===== -->
+<div class="slide" data-title="Multi-Agent">
+<h2>πŸ‘₯ Multi-Agent System</h2>
+<p>newOS4 can spawn <strong>specialized worker agents</strong> that run tasks in parallel. Each agent has its own role and capabilities.</p>
+<div class="grid-3" style="margin:10px 0">
+<div class="agent-card">
+<div class="agent-name">πŸ” Searcher</div>
+<div class="agent-role">Web research & data gathering</div>
+<div class="agent-caps"><span class="tag blue">web_search</span><span class="tag blue">read_file</span></div>
+</div>
+<div class="agent-card">
+<div class="agent-name">πŸ—οΈ Kernel Architect</div>
+<div class="agent-role">Code writing & system changes</div>
+<div class="agent-caps"><span class="tag orange">write_file</span><span class="tag orange">run_command</span></div>
+</div>
+<div class="agent-card">
+<div class="agent-name">πŸ“š Auto-Learner</div>
+<div class="agent-role">Pattern extraction & learning</div>
+<div class="agent-caps"><span class="tag purple">view_module</span><span class="tag purple">write_file</span></div>
+</div>
+</div>
+<div class="card">
+<h3 style="margin-top:0">How it works</h3>
+<ul>
+<li><strong>Agent Registry</strong> β€” agents register with capabilities and contracts</li>
+<li><strong>Lease System</strong> β€” tasks assigned via time-limited leases</li>
+<li><strong>Orchestrator</strong> β€” spawns, monitors, and kills agents</li>
+<li><strong>A2A Contracts</strong> β€” agents communicate via structured contracts</li>
+<li><strong>Failure Recovery</strong> β€” auto-restart policies, failure counting</li>
+</ul>
+</div>
+<p class="small">Current state: 3 agent types registered, 35 lifetime spawns. All idle/sleeping β€” ready for tasking.</p>
+</div>
+
+<!-- ===== SLIDE 7: SELF-HEALING ===== -->
+<div class="slide" data-title="Self-Healing">
+<h2>πŸ›‘οΈ Self-Healing System (NEW in v4.6.10)</h2>
+<p>The DebugSupervisorModule gives the system a full <strong>immune system</strong> β€” it catches errors, classifies them, finds root causes, and can auto-apply fixes.</p>
+<div class="flow">
+<div class="flow-step">
+<div class="flow-title">1. Error Interception</div>
+<div class="flow-desc">console.error Β· window.onerror Β· unhandledrejection Β· fetch failures Β· tool errors</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">2. Classification</div>
+<div class="flow-desc">Type (ReferenceError/TypeError/HTTP/timeout) Β· Severity (fatal/error/warning) Β· Category (module/network/tool/security/vfs)</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">3. Dedup & Persistence</div>
+<div class="flow-desc">Jaccard similarity 0.35 dedup Β· LRU eviction Β· localStorage-backed Β· quota monitoring</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">4. Root-Cause Analysis</div>
+<div class="flow-desc">Traces: tool fail β†’ module not loaded Β· HTTP β†’ network Β· ReferenceError β†’ bundle</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">5. Auto-Fix Pipeline</div>
+<div class="flow-desc">Confidence-gated: 0.7 = suggest to AI Β· 0.9 = auto-apply Β· fixes injected into AI system prompt</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">6. Self-Diagnostic</div>
+<div class="flow-desc">_healthy flag Β· fallback to original error log Β· health check command</div>
+</div>
+</div>
+<div class="card green">
+<p style="margin:0"><strong>6 terminal commands:</strong> <code>debug-stats</code> Β· <code>debug-history</code> Β· <code>debug-analyze</code> Β· <code>debug-trends</code> Β· <code>debug-fix</code> Β· <code>debug-health</code></p>
+</div>
+</div>
+
+<!-- ===== SLIDE 8: MEMORY & LEARNING ===== -->
+<div class="slide" data-title="Memory & Learning">
+<h2>🧬 Memory & Learning</h2>
+<p>The system doesn't start fresh each time. It has multiple memory systems:</p>
+<div class="grid-2">
+<div class="card blue">
+<h3 style="margin-top:0">πŸ“¦ Session Memory</h3>
+<ul style="font-size:.82rem">
+<li>Save/load sessions by date</li>
+<li>Recent session list</li>
+<li>Aggregate stats per session</li>
+<li>Terminal output history</li>
+</ul>
+</div>
+<div class="card purple">
+<h3 style="margin-top:0">πŸ‘€ User Profile</h3>
+<ul style="font-size:.82rem">
+<li>Preferred model</li>
+<li>Custom preferences</li>
+<li>Persistent across reloads</li>
+<li>Forgetting supported</li>
+</ul>
+</div>
+<div class="card green">
+<h3 style="margin-top:0">πŸŽ“ Skills Library</h3>
+<ul style="font-size:.82rem">
+<li>17 skills across 6 categories</li>
+<li>Procedural memory (how-to guides)</li>
+<li>Auto-loaded by context</li>
+<li>Create/patch/list/search</li>
+</ul>
+</div>
+<div class="card accent">
+<h3 style="margin-top:0">πŸ•ΈοΈ Memory Graph</h3>
+<ul style="font-size:.82rem">
+<li>83 nodes, 88+ edges</li>
+<li>File access patterns</li>
+<li>Task correlation</li>
+<li>Auto-growing knowledge base</li>
+</ul>
+</div>
+</div>
+<div class="card">
+<h3>🧠 Neural VFS</h3>
+<p class="small">The Virtual File System has a <strong>semantic search index</strong> β€” you can search files by concept, not just by name. <code>nvfs-resolve "security"</code> finds security-related files even if they're named differently.</p>
+<div style="display:flex;gap:4px;flex-wrap:wrap;margin-top:6px">
+<span class="pill">nvfs-index</span>
+<span class="pill">nvfs-resolve</span>
+<span class="pill">nvfs-status</span>
+<span class="pill">nvfs-tree</span>
+</div>
+</div>
+</div>
+
+<!-- ===== SLIDE 9: MODULE ECOSYSTEM ===== -->
+<div class="slide" data-title="Module Ecosystem">
+<h2>πŸ“¦ Module Ecosystem</h2>
+<p>43 modules total (22 core + 21 ext). Each module is a self-contained JS class with its own commands and lifecycle.</p>
+<h3>Core Modules (always loaded)</h3>
+<div class="table-scroll">
+<table>
+<tr><th>Module</th><th>Class</th><th>Key Commands</th></tr>
+<tr><td>AI Assistant</td><td>WebX11AIAssistantModule</td><td>ai, ask, ai-system</td></tr>
+<tr><td>Debug Supervisor</td><td>DebugSupervisorModule</td><td>debug-stats, debug-fix</td></tr>
+<tr><td>Terminal</td><td>WebX11SecurityManager</td><td>clear, help, security</td></tr>
+<tr><td>Virtual FS</td><td>VirtualFileSystem</td><td>save, load, import</td></tr>
+<tr><td>Neural VFS</td><td>NeuralVFSModule</td><td>nvfs-index, nvfs-resolve</td></tr>
+<tr><td>Ollama</td><td>OllamaModule</td><td>ollama, models, model-info</td></tr>
+<tr><td>Agent Registry</td><td>AgentRegistryModule</td><td>agent-list, agent-register</td></tr>
+<tr><td>Orchestrator</td><td>OrchestratorModule</td><td>orchestrate, orchestrator-spawn</td></tr>
+<tr><td>SearXNG</td><td>SearXNGModule</td><td>search, images, videos</td></tr>
+<tr><td>Server Monitor</td><td>ServerMonitorModule</td><td>server, system-health</td></tr>
+<tr><td>Config Manager</td><td>ConfigManagerModule</td><td>config, config-set</td></tr>
+<tr><td>Secret Vault</td><td>SecretVault</td><td>secret-set, secret-get</td></tr>
+<tr><td>Module Manager</td><td>ModuleManager</td><td>modules, loadmod</td></tr>
+<tr><td>Lease System</td><td>LeaseModule</td><td>lease-list, lease-create</td></tr>
+<tr><td>Web Fetcher</td><td>WebFetcherModule</td><td>fetch, web, extract</td></tr>
+<tr><td>System</td><td>SystemModule</td><td>help, status, logs</td></tr>
+<tr><td>Chat Studio</td><td>ChatStudioModule</td><td>chat</td></tr>
+<tr><td>Simple GUI</td><td>SimpleGUIModule</td><td>gui, gui-button</td></tr>
+<tr><td>AI Alias</td><td>WebXAIAliasModule</td><td>webxai, wx, webx</td></tr>
+</table>
+</div>
+<h3>Extension Modules (load on demand)</h3>
+<div style="display:flex;flex-wrap:wrap;gap:4px;margin-top:6px">
+<span class="pill">Editor</span><span class="pill">Shell</span><span class="pill">Cron</span>
+<span class="pill">WebDAV</span><span class="pill">Voice</span><span class="pill">Mindmap</span>
+<span class="pill">Floating UI</span><span class="pill">Media</span><span class="pill">JS Console</span>
+<span class="pill">File Manager</span><span class="pill">Finder</span><span class="pill">Theme</span>
+<span class="pill">Tutorial</span><span class="pill">WPM</span><span class="pill">Calc</span>
+<span class="pill">Diff</span><span class="pill">BusyBox</span><span class="pill">Crypto/Gzip</span>
+<span class="pill">Alias</span><span class="pill">Debug Panel</span><span class="pill">Skill Pack</span>
+</div>
+</div>
+
+<!-- ===== SLIDE 10: WHAT'S BEEN ACCOMPLISHED ===== -->
+<div class="slide" data-title="Accomplished">
+<h2>βœ… What We've Built So Far</h2>
+<div class="timeline">
+<div class="t-item done">
+<div class="t-date">Phase 1</div>
+<div class="t-title">System Foundation</div>
+<p class="small">44 modules Β· 17 skills Β· 296 files Β· 90+ commands Β· terminal Β· VFS Β· security</p>
+</div>
+<div class="t-item done">
+<div class="t-date">Phase 2</div>
+<div class="t-title">AI Integration</div>
+<p class="small">Agent loop Β· multi-model routing Β· Ollama integration Β· smart context profiles</p>
+</div>
+<div class="t-item done">
+<div class="t-date">Phase 3</div>
+<div class="t-title">Multi-Agent System</div>
+<p class="small">Agent registry Β· orchestrator Β· leases Β· A2A contracts Β· 35 lifetime agent spawns</p>
+</div>
+<div class="t-item done">
+<div class="t-date">Phase 4</div>
+<div class="t-title">Memory & Persistence</div>
+<p class="small">Session save/load Β· user profile Β· skills library Β· memory graph (83 nodes) Β· Neural VFS</p>
+</div>
+<div class="t-item done">
+<div class="t-date">Phase 5</div>
+<div class="t-title">Self-Healing (v4.6.10)</div>
+<p class="small">DebugSupervisorModule Β· error interception Β· root-cause analysis Β· auto-fix pipeline</p>
+</div>
+<div class="t-item done">
+<div class="t-date">Phase 6</div>
+<div class="t-title">Cloud & Sync</div>
+<p class="small">WebDAV backup Β· crypto/gzip Β· file manager Β· floating UI Β· voice control</p>
+</div>
+<div class="t-item active">
+<div class="t-date">Phase 7 β€” Current</div>
+<div class="t-title">Custom Model Training</div>
+<p class="small">Planning phase β€” dataset strategy, MoE architecture, budget defined</p>
+</div>
+<div class="t-item future">
+<div class="t-date">Phase 8 β€” Next</div>
+<div class="t-title">Custom MoE Model</div>
+<p class="small">QLoRA fine-tune β†’ MoE deep training β†’ self-hosted inference</p>
+</div>
+</div>
+<div class="stat-row">
+<div class="stat-box"><div class="num" style="color:var(--green)">6/6</div><div class="label">Planning Done</div></div>
+<div class="stat-box"><div class="num" style="color:var(--accent)">1</div><div class="label">Active Phase</div></div>
+<div class="stat-box"><div class="num" style="color:var(--text2)">1</div><div class="label">Upcoming</div></div>
+<div class="stat-box"><div class="num" style="color:var(--green)">€0</div><div class="label">Spent on AI</div></div>
+</div>
+</div>
+
+<!-- ===== SLIDE 11: THE PROBLEM ===== -->
+<div class="slide" data-title="The Problem">
+<h2>⚠️ The Current Bottleneck</h2>
+<p>The system is powerful, but it depends on <strong>external LLMs</strong> for intelligence. Here's why that limits us:</p>
+<div class="vs-box">
+<div class="vs-side left">
+<h4>❌ Current State</h4>
+<ul>
+<li>Depends on Ollama-hosted models</li>
+<li>Generic models β€” no domain specialization</li>
+<li>No memory of past sessions baked in</li>
+<li>Token costs scale with usage (8M/week)</li>
+<li>Latency: 2-27s avg per request</li>
+<li>Can't customize reasoning style</li>
+<li>No multi-token generation</li>
+<li>Model behavior changes with updates</li>
+</ul>
+</div>
+<div class="vs-side right">
+<h4>βœ… With Custom Model</h4>
+<ul>
+<li>Self-hosted, fully owned</li>
+<li>Specialized for OS operations</li>
+<li>Training data from real sessions</li>
+<li>Fixed compute cost (one-time training)</li>
+<li>Latency: <0.5s with speculative decoding</li>
+<li>Custom reasoning chain style</li>
+<li>Multi-token generation (Medusa heads)</li>
+<li>Full control β€” no surprise updates</li>
+</ul>
+</div>
+</div>
+<div class="card red">
+<h3 style="margin-top:0">The Core Insight</h3>
+<p style="margin:0">The system already has <strong>500 real interaction sessions</strong>, <strong>8M tokens of reasoning data</strong>, and <strong>17 skills</strong> with structured procedures. This is a ready-made training dataset. No other project has this kind of organic, domain-specific data.</p>
+</div>
+</div>
+
+<!-- ===== SLIDE 12: HOW CUSTOM MODEL IMPROVES ===== -->
+<div class="slide" data-title="Training Impact">
+<h2>πŸš€ How a Custom Model Improves Everything</h2>
+<h3>1. Speed β€” Multi-Token Generation</h3>
+<div class="vs-box">
+<div class="vs-side left">
+<h4>Current: 1 token/step</h4>
+<ul>
+<li>Sequential generation</li>
+<li>~20-40 tokens/sec</li>
+<li>Long responses take 10-30s</li>
+</ul>
+</div>
+<div class="vs-side right">
+<h4>With Medusa Heads: 3-5 tokens/step</h4>
+<ul>
+<li>Parallel prediction branches</li>
+<li>~100-200 tokens/sec</li>
+<li>Same response in 2-5s</li>
+</ul>
+</div>
+</div>
+<h3>2. Intelligence β€” Domain Specialization</h3>
+<div class="card blue">
+<ul>
+<li><strong>Module management</strong> β€” model knows the 43-module API without RAG lookup</li>
+<li><strong>Error diagnosis</strong> β€” trained on debug-history patterns, faster root-cause</li>
+<li><strong>Code generation</strong> β€” knows the system's architecture, generates compatible code</li>
+<li><strong>Command routing</strong> β€” maps natural language to 90+ commands accurately</li>
+<li><strong>Agent delegation</strong> β€” learns optimal task decomposition from past sessions</li>
+</ul>
+</div>
+<h3>3. Cost β€” One-Time Training vs Endless API</h3>
+<div class="card green">
+<table>
+<tr><th>Approach</th><th>Cost Model</th><th>Per Week</th></tr>
+<tr><td>Current (Ollama API)</td><td>Per-request tokens</td><td>~8M tokens</td></tr>
+<tr><td>Custom Model (fine-tuned)</td><td>One-time training</td><td>~0 marginal cost</td></tr>
+<tr><td>Custom MoE (full train)</td><td>One-time + hosting</td><td>~0 marginal cost</td></tr>
+</table>
+</div>
+<h3>4. MoE Architecture β€” Sparse Expert Routing</h3>
+<div class="card purple">
+<ul>
+<li><strong>Expert 1:</strong> System operations (VFS, modules, config)</li>
+<li><strong>Expert 2:</strong> Code generation & debugging</li>
+<li><strong>Expert 3:</strong> Web research & information synthesis</li>
+<li><strong>Expert 4:</strong> Natural language & user communication</li>
+<li><strong>Router:</strong> Dynamically selects 2 experts per token β€” 2x speed, same quality</li>
+</ul>
+<p class="small" style="margin-top:6px">Only the relevant experts activate β†’ less compute per token β†’ faster + cheaper inference.</p>
+</div>
+</div>
+
+<!-- ===== SLIDE 13: TRAINING PIPELINE ===== -->
+<div class="slide" data-title="Training Pipeline">
+<h2>πŸ”¬ Training Pipeline</h2>
+<p>How we turn system data into a custom model:</p>
+<div class="flow">
+<div class="flow-step">
+<div class="flow-title">Phase 0 β€” Dataset Engineering</div>
+<div class="flow-desc">Extract 500 sessions Β· 8M tokens Β· 17 skills Β· error/fix pairs Β· format as instruction-response pairs Β· synthetic expansion</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">Phase 1 β€” QLoRA Proof of Concept</div>
+<div class="flow-desc">Fine-tune Qwen2.5-14B with Unsloth on 1Γ— A100 (20 hrs) Β· validate on held-out sessions Β· cost: €35-100</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">Phase 2 β€” MoE Fine-Tune</div>
+<div class="flow-desc">Fine-tune Mixtral 8x7B MoE on full dataset Β· 2Γ— A100 (48 hrs) Β· validate expert routing Β· cost: €200-500</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">Phase 3 β€” Deep MoE + Multi-Token</div>
+<div class="flow-desc">DeepSeek-V3 or Mixtral 8x22B + Medusa heads Β· 8Γ— H100 cluster (72 hrs) Β· cost: €2,000-8,000</div>
+</div>
+<div class="flow-step">
+<div class="flow-title">Phase 4 β€” Deploy & Integrate</div>
+<div class="flow-desc">Self-host on local GPU or rented instance Β· wire into Ollama module Β· replace external models Β· cost: €0-200/mo</div>
+</div>
+</div>
+<div class="highlight-box">
+<h3 style="margin-top:0">πŸ“Š The Ask</h3>
+<p style="margin:0"><strong>Phase 0 + Phase 1 only: €300-500</strong> β€” proves the concept works. Phase 2/3 funding decided after PoC results.</p>
+</div>
+</div>
+
+<!-- ===== SLIDE 14: WHAT WE HAVE THAT OTHERS DON'T ===== -->
+<div class="slide" data-title="Unique Advantages">
+<h2>πŸ† What We Have That Others Don't</h2>
+<div class="card accent">
+<h3 style="margin-top:0">1. Organic Training Data</h3>
+<p>Most AI projects buy or scrape data. We have <strong>500 real sessions</strong> of a human working with an AI on system-building tasks. This is gold-standard data.</p>
+</div>
+<div class="card green">
+<h3 style="margin-top:0">2. Built-in Evaluation Harness</h3>
+<p>The system has a <strong>module test pipeline</strong> (edit β†’ test β†’ health check β†’ regression). We can evaluate model quality by running it against the actual system β€” no external benchmark needed.</p>
+</div>
+<div class="card blue">
+<h3 style="margin-top:0">3. Closed-Loop Improvement</h3>
+<p>DebugSupervisorModule captures errors β†’ auto-fix suggestions β†’ model learns from fixes β†’ fewer errors next time. The system <strong>teaches itself</strong>.</p>
+</div>
+<div class="card purple">
+<h3 style="margin-top:0">4. Multi-Model Today, Custom Tomorrow</h3>
+<p>We already run 4 models (glm-5.2, gemma4:31b, mistral-large, minimax-m3). The routing infrastructure is built. A custom model just becomes <strong>another model in the pool</strong> β€” but specialized.</p>
+</div>
+<div class="card red">
+<h3 style="margin-top:0">5. Skills as Structured Training Data</h3>
+<p>17 skills are already written as step-by-step procedures. These are perfect <strong>instruction-response training pairs</strong> β€” zero formatting work needed.</p>
+</div>
+</div>
+
+<!-- ===== SLIDE 15: RISK & FALLBACK ===== -->
+<div class="slide" data-title="Risk & Fallback">
+<h2>βš–οΈ Risks & Fallback Plans</h2>
+<h3>Risk Matrix</h3>
+<div class="table-scroll">
+<table class="compare-table">
+<tr><th>Risk</th><th>Prob</th><th>Impact</th><th>Mitigation</th></tr>
+<tr><td>QLoRA overfitting</td><td>Medium</td><td>Low</td><td>Held-out validation Β· early stopping</td></tr>
+<tr><td>MoE training unstable</td><td>Low</td><td>High</td><td>Start with Mixtral (proven MoE) Β· skip Phase 3</td></tr>
+<tr><td>GPU costs exceed budget</td><td>Medium</td><td>Medium</td><td>Spot instances Β· Unsloth 2x efficiency</td></tr>
+<tr><td>Dataset too small</td><td>Low</td><td>Medium</td><td>Synthetic expansion Β· augment with skills</td></tr>
+<tr><td>Model quality < baseline</td><td>Low</td><td>High</td><td>PoC validates before committing funds</td></tr>
+<tr><td>Inference too slow</td><td>Low</td><td>Low</td><td>Quantize to 4-bit Β· Medusa heads</td></tr>
+</table>
+</div>
+<h3>Fallback Plans</h3>
+<div class="card">
+<ul>
+<li><strong>Ultra-budget (€20):</strong> Google Colab free tier + QLoRA 7B model β€” proves concept with zero risk</li>
+<li><strong>Zero-budget (€0):</strong> Enhanced RAG pipeline β€” index all sessions/skills into Neural VFS, retrieve context dynamically. No training, but better prompting.</li>
+<li><strong>Mid-budget (€500):</strong> Phase 0+1 only β€” QLoRA on 14B, self-host on existing Ollama setup</li>
+<li><strong>Full vision (€8K+):</strong> All phases β€” custom MoE with multi-token generation</li>
+</ul>
+</div>
+</div>
+
+<!-- ===== SLIDE 16: SUMMARY ===== -->
+<div class="slide" data-title="Summary">
+<h2>πŸ“‹ Summary for Review</h2>
+<div class="card blue">
+<h3 style="margin-top:0">What exists today</h3>
+<div class="stat-row" style="margin-top:6px">
+<div class="stat-box"><div class="num">44</div><div class="label">Modules</div></div>
+<div class="stat-box"><div class="num">90+</div><div class="label">Commands</div></div>
+<div class="stat-box"><div class="num">17</div><div class="label">Skills</div></div>
+<div class="stat-box"><div class="num">296</div><div class="label">Files</div></div>
+</div>
+<div class="stat-row">
+<div class="stat-box"><div class="num">3</div><div class="label">Agent Types</div></div>
+<div class="stat-box"><div class="num">4</div><div class="label">LLM Models</div></div>
+<div class="stat-box"><div class="num">500</div><div class="label">Sessions</div></div>
+<div class="stat-box"><div class="num">8M</div><div class="label">Tokens/Week</div></div>
+</div>
+</div>
+<div class="card accent">
+<h3 style="margin-top:0">What custom training adds</h3>
+<ul>
+<li>⚑ <strong>5-10x faster</strong> inference (multi-token generation)</li>
+<li>🧠 <strong>Domain-specialized</strong> (OS operations, debugging, code gen)</li>
+<li>πŸ’° <strong>Near-zero marginal cost</strong> after one-time training</li>
+<li>πŸ”’ <strong>Full ownership</strong> β€” no external model dependency</li>
+<li>πŸ”„ <strong>Self-improving</strong> β€” learns from its own error fixes</li>
+</ul>
+</div>
+<div class="card green">
+<h3 style="margin-top:0">Why now</h3>
+<ul>
+<li>We have 500 sessions of real training data already</li>
+<li>QLoRA + Unsloth make training 70% cheaper than 1 year ago</li>
+<li>The system's self-healing layer generates new training data automatically</li>
+<li>The Ollama integration is already built β€” deployment is plug-and-play</li>
+</ul>
+</div>
+</div>
+
+<!-- ===== SLIDE 17: THANK YOU ===== -->
+<div class="slide title-slide" data-title="Thank You">
+<h1>🐴πŸ”₯</h1>
+<h2 style="text-align:center">Year of the Firehorse</h2>
+<p class="subtitle" style="margin-top:10px">newOS4 is a living system that can build, repair, and improve itself.</p>
+<p class="subtitle" style="margin-top:4px">A custom model makes it truly autonomous.</p>
+<div class="highlight-box" style="margin-top:20px;text-align:center">
+<h3 style="text-align:center;margin-top:0">The Ask</h3>
+<p style="text-align:center;margin:0"><strong>€300-500</strong> for Phase 0+1 (dataset + PoC)</p>
+<p class="small" style="text-align:center;margin-top:6px">Proves the concept. Everything else is optional.</p>
+</div>
+<p class="small" style="margin-top:24px;text-align:center">
+This is not a pitch for a product.<br>
+This is a plan to give a system its own brain.
+</p>
+<p style="margin-top:20px;text-align:center;font-size:1.5rem">πŸ™</p>
+</div>
+
+</div>
+
+<!-- ===== NAVIGATION ===== -->
+<div class="nav">
+<button class="nav-btn" id="prevBtn" onclick="nav(-1)">← Prev</button>
+<div style="display:flex;align-items:center;gap:10px">
+<div class="dots" id="dots"></div>
+<span class="counter" id="counter">1/17</span>
+</div>
+<button class="nav-btn" id="nextBtn" onclick="nav(1)">Next β†’</button>
+</div>
+
+<script>
+let current=0;
+const slides=document.querySelectorAll('.slide');
+const total=slides.length;
+const dotsEl=document.getElementById('dots');
+const counterEl=document.getElementById('counter');
+const prevBtn=document.getElementById('prevBtn');
+const nextBtn=document.getElementById('nextBtn');
+
+for(let i=0;i<total;i++){
+ const d=document.createElement('div');
+ d.className='dot'+(i===0?' active':'')+(i<current?' done':'');
+ d.onclick=()=>{current=i;render()};
+ dotsEl.appendChild(d);
+}
+
+function render(){
+ slides.forEach((s,i)=>s.classList.toggle('active',i===current));
+ const dots=dotsEl.querySelectorAll('.dot');
+ dots.forEach((d,i)=>{
+ d.classList.remove('active','done');
+ if(i<current)d.classList.add('done');
+ if(i===current)d.classList.add('active');
+ });
+ counterEl.textContent=(current+1)+'/'+total;
+ prevBtn.disabled=current===0;
+ nextBtn.disabled=current===total-1;
+}
+
+function nav(dir){
+ current=Math.max(0,Math.min(total-1,current+dir));
+ render();
+ window.scrollTo(0,0);
+}
+
+document.addEventListener('keydown',e=>{
+ if(e.key==='ArrowLeft')nav(-1);
+ if(e.key==='ArrowRight')nav(1);
+});
+
+let startX=0;
+document.addEventListener('touchstart',e=>{startX=e.touches[0].clientX});
+document.addEventListener('touchend',e=>{
+ const diff=e.changedTouches[0].clientX-startX;
+ if(Math.abs(diff)>50)nav(diff>0?-1:1);
+});
+
+render();
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/downloads/gunes-uygarligi.html b/downloads/gunes-uygarligi.html
new file mode 100644
index 0000000..ce12a3d
--- /dev/null
+++ b/downloads/gunes-uygarligi.html
@@ -0,0 +1,1379 @@
+<!DOCTYPE html>
+<html lang="tr">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>GΓΌneş Uygarlığı Hareketi β€” newOS Entegre Manifestosu</title>
+<meta name="description" content="Güneş Uygarlığı: Sürdürülebilir, adil, güneş enerjisi temelli yeni bir yaşam. newOS tasarım sistemi ve ajan mimarisiyle bütünleşik tek-sayfa manifesto.">
+<meta name="theme-color" content="#FFD700">
+<meta name="color-scheme" content="dark">
+
+<!-- Open Graph -->
+<meta property="og:title" content="Güneş Uygarlığı Hareketi">
+<meta property="og:description" content="Güneş enerjisi temelli, halktan yana, çevreye saygılı bir gelecek inşası için manifesto.">
+<meta property="og:type" content="article">
+<meta property="og:locale" content="tr_TR">
+<meta property="og:site_name" content="Güneş Uygarlığı">
+
+<!-- Twitter Card -->
+<meta name="twitter:card" content="summary_large_image">
+<meta name="twitter:title" content="Güneş Uygarlığı Hareketi">
+<meta name="twitter:description" content="Güneş enerjisi temelli yeni bir yaşam manifestosu.">
+
+<!-- PWA Manifest (commented - gerΓ§ek projede app.manifest olarak ayrΔ± dosya) -->
+<!--
+{
+ "name": "Güneş Uygarlığı",
+ "short_name": "GüneşUygarlığı",
+ "description": "Güneş enerjisi temelli, sürdürülebilir ve adil bir gelecek manifestosu",
+ "start_url": "/spaces/gunesuygarligi/",
+ "display": "standalone",
+ "background_color": "#0a0a0a",
+ "theme_color": "#FFD700",
+ "lang": "tr",
+ "icons": [
+ {"src": "/assets/sun-192.png", "sizes": "192x192", "type": "image/png"},
+ {"src": "/assets/sun-512.png", "sizes": "512x512", "type": "image/png"}
+ ]
+}
+-->
+
+<!-- Google Fonts: preconnect + display=swap -->
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600;700&family=Inter:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet">
+
+<!-- newOS Kâprüsü: manifest.json meta (newOS tarayıcıda window.newOS sağlar) -->
+<script>
+// Standalone fallback: newOS yüklü değilse graceful no-op
+window.newOS = window.newOS || {
+ version: 'standalone-fallback',
+ ready: true,
+ bridge: {
+ readManifest: () => { try { return JSON.parse(localStorage.getItem('newos.user') || '{}'); } catch (e) { return {}; } },
+ writeManifest: (data) => { try { localStorage.setItem('newos.user', JSON.stringify(data)); } catch (e) {} },
+ theme: () => { try { return localStorage.getItem('newos.theme') || 'dark'; } catch (e) { return 'dark'; } },
+ setTheme: (t) => { try { localStorage.setItem('newos.theme', t); document.documentElement.dataset.theme = t; } catch (e) {} },
+ events: { emit: (name, data) => console.log('[newOS event]', name, data) },
+ on: () => {}, off: () => {},
+ agent: { queue: (task) => console.log('[newOS agent]', task) }
+ }
+};
+</script>
+
+<style>
+/* ================================================================
+ newOS TASARIM TOKEN'LARI
+ ================================================================ */
+:root {
+ /* newOS kâprüsü: Bu değişkenler newOS.theme ile senkronize olur */
+ --nui-radius: 12px;
+ --nui-radius-lg: 20px;
+ --nui-spacing: 1rem;
+ --nui-font-mono: 'IBM Plex Mono', ui-monospace, monospace;
+ --nui-shadow: 0 8px 32px rgba(0,0,0,0.4);
+
+ /* Yerel palet β€” GΓΌneş Uygarlığı temalarΔ± */
+ --color-bg: #0a0a0a;
+ --color-bg-soft: #141414;
+ --color-bg-elev: #1c1c1c;
+ --color-fg: #f4f4f4;
+ --color-fg-dim: #b8b8b8;
+ --color-fg-mute: #888;
+ --color-gold: #FFD700;
+ --color-gold-soft: rgba(255, 215, 0, 0.12);
+ --color-dawn: #FF8C42;
+ --color-line: rgba(255, 215, 0, 0.18);
+ --color-line-soft: rgba(255, 255, 255, 0.08);
+
+ /* Tipografi */
+ --font-serif: 'Cormorant Garamond', Georgia, serif;
+ --font-sans: 'Inter', system-ui, -apple-system, sans-serif;
+ --font-mono: var(--nui-font-mono);
+
+ /* Tipografi âlçeği */
+ --fs-xs: 0.78rem;
+ --fs-sm: 0.9rem;
+ --fs-base: 1rem;
+ --fs-lg: 1.18rem;
+ --fs-xl: 1.5rem;
+ --fs-2xl: 2rem;
+ --fs-3xl: 2.75rem;
+ --fs-4xl: clamp(2.4rem, 5vw, 4.2rem);
+
+ /* Geçişler */
+ --ease: cubic-bezier(0.4, 0, 0.2, 1);
+ --dur: 0.28s;
+}
+
+[data-theme="light"] {
+ --color-bg: #fafaf7;
+ --color-bg-soft: #f0efe8;
+ --color-bg-elev: #ffffff;
+ --color-fg: #1a1a1a;
+ --color-fg-dim: #4a4a4a;
+ --color-fg-mute: #777;
+ --color-line: rgba(255, 143, 0, 0.22);
+ --color-line-soft: rgba(0, 0, 0, 0.08);
+}
+
+/* ================================================================
+ RESET & TEMEL
+ ================================================================ */
+*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
+html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
+body {
+ font-family: var(--font-sans);
+ font-size: var(--fs-base);
+ line-height: 1.65;
+ color: var(--color-fg);
+ background: var(--color-bg);
+ background-image:
+ radial-gradient(ellipse at top, rgba(255, 140, 66, 0.06) 0%, transparent 50%),
+ radial-gradient(ellipse at bottom right, rgba(255, 215, 0, 0.04) 0%, transparent 60%);
+ background-attachment: fixed;
+ overflow-x: hidden;
+}
+img, svg { max-width: 100%; display: block; }
+a { color: var(--color-gold); text-decoration: none; transition: color var(--dur) var(--ease); }
+a:hover { color: var(--color-dawn); }
+a:focus-visible, button:focus-visible { outline: 2px solid var(--color-gold); outline-offset: 3px; border-radius: 2px; }
+
+h1, h2, h3 { font-family: var(--font-serif); font-weight: 600; line-height: 1.18; letter-spacing: -0.01em; }
+h1 { font-size: var(--fs-4xl); font-weight: 700; }
+h2 { font-size: var(--fs-3xl); }
+h3 { font-size: var(--fs-2xl); }
+p { max-width: 68ch; }
+.mono { font-family: var(--font-mono); font-size: var(--fs-sm); letter-spacing: 0.04em; }
+.eyebrow {
+ font-family: var(--font-mono);
+ font-size: var(--fs-xs);
+ letter-spacing: 0.18em;
+ text-transform: uppercase;
+ color: var(--color-gold);
+ display: inline-block;
+ margin-bottom: 0.75rem;
+}
+
+/* Erişilebilirlik: skip link */
+.skip-link {
+ position: absolute;
+ top: -40px;
+ left: 0;
+ background: var(--color-gold);
+ color: var(--color-bg);
+ padding: 0.6rem 1rem;
+ z-index: 1000;
+ font-weight: 600;
+ border-radius: 0 0 var(--nui-radius) 0;
+}
+.skip-link:focus { top: 0; }
+
+/* ================================================================
+ NAVΔ°GASYON
+ ================================================================ */
+.topnav {
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ background: rgba(10, 10, 10, 0.85);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ border-bottom: 1px solid var(--color-line-soft);
+}
+.topnav__inner {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 0.9rem 1.25rem;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+}
+.brand {
+ display: flex;
+ align-items: center;
+ gap: 0.6rem;
+ font-family: var(--font-serif);
+ font-size: var(--fs-lg);
+ font-weight: 600;
+ color: var(--color-fg);
+}
+.brand__sun {
+ width: 28px; height: 28px;
+ animation: rotate-slow 18s linear infinite;
+}
+.nav-links {
+ display: flex;
+ gap: 1.5rem;
+ list-style: none;
+}
+.nav-links a {
+ color: var(--color-fg-dim);
+ font-size: var(--fs-sm);
+ font-weight: 500;
+ position: relative;
+ padding: 0.25rem 0;
+}
+.nav-links a::after {
+ content: '';
+ position: absolute;
+ bottom: -2px; left: 0;
+ width: 0; height: 1px;
+ background: var(--color-gold);
+ transition: width var(--dur) var(--ease);
+}
+.nav-links a:hover { color: var(--color-gold); }
+.nav-links a:hover::after { width: 100%; }
+
+.nav-toggle {
+ display: none;
+ background: transparent;
+ border: 1px solid var(--color-line);
+ color: var(--color-fg);
+ padding: 0.4rem 0.7rem;
+ border-radius: 6px;
+ cursor: pointer;
+ font-family: var(--font-mono);
+ font-size: var(--fs-sm);
+}
+
+@media (max-width: 720px) {
+ .nav-links { display: none; position: absolute; top: 100%; right: 0; left: 0; flex-direction: column; gap: 0; background: var(--color-bg-elev); border-bottom: 1px solid var(--color-line-soft); padding: 1rem 1.25rem; }
+ .nav-links.open { display: flex; }
+ .nav-links a { padding: 0.6rem 0; border-bottom: 1px solid var(--color-line-soft); }
+ .nav-links a:last-child { border-bottom: 0; }
+ .nav-toggle { display: inline-block; }
+}
+
+/* ================================================================
+ LAYOUT
+ ================================================================ */
+.container { max-width: 1200px; margin: 0 auto; padding: 0 1.25rem; }
+section { padding: 5rem 0; scroll-margin-top: 80px; }
+section + section { border-top: 1px solid var(--color-line-soft); }
+
+/* ================================================================
+ HERO
+ ================================================================ */
+.hero {
+ min-height: 88vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ text-align: center;
+ padding: 4rem 1.25rem 5rem;
+ position: relative;
+}
+.hero__sun {
+ width: clamp(180px, 30vw, 280px);
+ height: clamp(180px, 30vw, 280px);
+ margin: 0 auto 2rem;
+ position: relative;
+ filter: drop-shadow(0 0 40px rgba(255, 215, 0, 0.35));
+}
+.hero__sun svg { width: 100%; height: 100%; }
+.hero__sun::before {
+ content: '';
+ position: absolute;
+ inset: -30%;
+ background: radial-gradient(circle, rgba(255, 215, 0, 0.18) 0%, transparent 60%);
+ animation: pulse 4s ease-in-out infinite;
+ z-index: -1;
+}
+.hero h1 { margin-bottom: 1rem; max-width: 18ch; margin-left: auto; margin-right: auto; }
+.hero h1 .accent { color: var(--color-gold); font-style: italic; }
+.hero__lede {
+ font-size: var(--fs-lg);
+ color: var(--color-fg-dim);
+ max-width: 56ch;
+ margin: 0 auto 2.5rem;
+ line-height: 1.55;
+}
+.hero__ctas {
+ display: flex;
+ gap: 0.8rem;
+ justify-content: center;
+ flex-wrap: wrap;
+}
+
+/* Buttons */
+.btn {
+ display: inline-block;
+ padding: 0.85rem 1.6rem;
+ border-radius: var(--nui-radius);
+ font-weight: 600;
+ font-size: var(--fs-base);
+ font-family: var(--font-sans);
+ cursor: pointer;
+ border: 1px solid transparent;
+ transition: all var(--dur) var(--ease);
+ text-align: center;
+}
+.btn--primary {
+ background: var(--color-gold);
+ color: var(--color-bg);
+ box-shadow: 0 4px 16px rgba(255, 215, 0, 0.25);
+}
+.btn--primary:hover {
+ background: var(--color-dawn);
+ color: var(--color-bg);
+ transform: translateY(-2px);
+ box-shadow: 0 6px 20px rgba(255, 140, 66, 0.4);
+}
+.btn--ghost {
+ background: transparent;
+ color: var(--color-fg);
+ border-color: var(--color-line);
+}
+.btn--ghost:hover {
+ border-color: var(--color-gold);
+ color: var(--color-gold);
+ background: var(--color-gold-soft);
+}
+
+@keyframes pulse {
+ 0%, 100% { transform: scale(1); opacity: 0.6; }
+ 50% { transform: scale(1.15); opacity: 0.9; }
+}
+@keyframes rotate-slow {
+ from { transform: rotate(0); }
+ to { transform: rotate(360deg); }
+}
+
+/* ================================================================
+ PORTAL CARDS
+ ================================================================ */
+.section-head {
+ text-align: center;
+ margin-bottom: 3rem;
+}
+.section-head h2 { margin-bottom: 0.6rem; }
+.section-head p { color: var(--color-fg-dim); margin: 0 auto; }
+
+.cards {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 1.25rem;
+}
+.card {
+ background: var(--color-bg-elev);
+ border: 1px solid var(--color-line-soft);
+ border-radius: var(--nui-radius-lg);
+ padding: 1.75rem;
+ text-decoration: none;
+ color: var(--color-fg);
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+ transition: all var(--dur) var(--ease);
+ position: relative;
+ overflow: hidden;
+}
+.card::before {
+ content: '';
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ height: 2px;
+ background: linear-gradient(90deg, transparent, var(--color-gold), transparent);
+ opacity: 0;
+ transition: opacity var(--dur) var(--ease);
+}
+.card:hover {
+ transform: translateY(-4px);
+ border-color: var(--color-gold);
+ background: linear-gradient(180deg, var(--color-bg-elev) 0%, rgba(255, 215, 0, 0.04) 100%);
+ box-shadow: var(--nui-shadow);
+}
+.card:hover::before { opacity: 1; }
+.card__icon {
+ width: 48px; height: 48px;
+ background: var(--color-gold-soft);
+ border-radius: 12px;
+ display: flex; align-items: center; justify-content: center;
+ color: var(--color-gold);
+ font-size: 1.4rem;
+ font-family: var(--font-serif);
+ font-weight: 700;
+}
+.card h3 { font-size: var(--fs-xl); }
+.card p { color: var(--color-fg-dim); font-size: var(--fs-sm); margin: 0; }
+.card__arrow {
+ align-self: flex-end;
+ color: var(--color-gold);
+ font-family: var(--font-mono);
+ font-size: var(--fs-sm);
+ margin-top: 0.5rem;
+}
+
+/* ================================================================
+ MANIFESTO
+ ================================================================ */
+.manifesto {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 3rem;
+}
+.manifesto__items {
+ list-style: none;
+ counter-reset: manifest;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+.manifesto__items li {
+ counter-increment: manifest;
+ background: var(--color-bg-soft);
+ border-left: 3px solid var(--color-gold);
+ border-radius: 0 var(--nui-radius) var(--nui-radius) 0;
+ padding: 1.1rem 1.25rem 1.1rem 3.25rem;
+ position: relative;
+}
+.manifesto__items li::before {
+ content: counter(manifest, decimal-leading-zero);
+ position: absolute;
+ left: 1.1rem;
+ top: 1.15rem;
+ font-family: var(--font-mono);
+ color: var(--color-gold);
+ font-weight: 600;
+ font-size: var(--fs-sm);
+}
+.manifesto__items strong { color: var(--color-gold); display: block; margin-bottom: 0.25rem; }
+
+.pillars {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
+ gap: 1rem;
+ margin-top: 2rem;
+}
+.pillar {
+ text-align: center;
+ padding: 1.25rem 1rem;
+ background: var(--color-bg-soft);
+ border-radius: var(--nui-radius);
+ border: 1px solid var(--color-line-soft);
+}
+.pillar__num {
+ font-family: var(--font-mono);
+ font-size: var(--fs-xs);
+ color: var(--color-gold);
+ letter-spacing: 0.12em;
+ margin-bottom: 0.4rem;
+}
+.pillar h4 {
+ font-family: var(--font-serif);
+ font-size: var(--fs-lg);
+ color: var(--color-fg);
+ margin-bottom: 0.3rem;
+}
+.pillar p { font-size: var(--fs-sm); color: var(--color-fg-dim); margin: 0; }
+
+/* ================================================================
+ ENERJΔ° VERΔ°LERΔ°
+ ================================================================ */
+.energy {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 2.5rem;
+ align-items: start;
+}
+@media (max-width: 880px) { .energy { grid-template-columns: 1fr; } }
+
+.stats {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 0.8rem;
+ margin-top: 1.5rem;
+}
+.stat {
+ background: var(--color-bg-soft);
+ border: 1px solid var(--color-line-soft);
+ border-radius: var(--nui-radius);
+ padding: 1.1rem;
+}
+.stat__value {
+ font-family: var(--font-serif);
+ font-size: var(--fs-2xl);
+ color: var(--color-gold);
+ font-weight: 700;
+ line-height: 1;
+}
+.stat__label { font-size: var(--fs-sm); color: var(--color-fg-dim); margin-top: 0.3rem; }
+
+.solution-list {
+ list-style: none;
+ margin-top: 1.25rem;
+ display: flex;
+ flex-direction: column;
+ gap: 0.6rem;
+}
+.solution-list li {
+ padding-left: 1.5rem;
+ position: relative;
+ color: var(--color-fg-dim);
+}
+.solution-list li::before {
+ content: 'β˜€';
+ position: absolute;
+ left: 0;
+ color: var(--color-gold);
+ font-size: 0.9em;
+}
+
+/* ================================================================
+ ARŞİV
+ ================================================================ */
+.archive-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
+ gap: 1rem;
+ margin-top: 1.5rem;
+}
+.archive-item {
+ background: var(--color-bg-soft);
+ border: 1px solid var(--color-line-soft);
+ border-radius: var(--nui-radius);
+ padding: 1.1rem;
+ transition: all var(--dur) var(--ease);
+}
+.archive-item:hover {
+ border-color: var(--color-gold);
+ transform: translateY(-2px);
+}
+.archive-item__type {
+ font-family: var(--font-mono);
+ font-size: var(--fs-xs);
+ color: var(--color-gold);
+ letter-spacing: 0.1em;
+ text-transform: uppercase;
+ margin-bottom: 0.4rem;
+}
+.archive-item h4 {
+ font-family: var(--font-serif);
+ font-size: var(--fs-lg);
+ color: var(--color-fg);
+ margin-bottom: 0.3rem;
+ line-height: 1.25;
+}
+.archive-item p { font-size: var(--fs-sm); color: var(--color-fg-dim); margin: 0; }
+
+/* ================================================================
+ KATILIM
+ ================================================================ */
+.steps {
+ counter-reset: step;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+ margin-top: 2rem;
+ max-width: 720px;
+ margin-left: auto;
+ margin-right: auto;
+}
+.step {
+ counter-increment: step;
+ background: var(--color-bg-soft);
+ border: 1px solid var(--color-line-soft);
+ border-radius: var(--nui-radius);
+ padding: 1.25rem 1.25rem 1.25rem 4.5rem;
+ position: relative;
+}
+.step::before {
+ content: counter(step);
+ position: absolute;
+ left: 1.25rem;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 38px; height: 38px;
+ background: var(--color-gold);
+ color: var(--color-bg);
+ border-radius: 50%;
+ display: flex; align-items: center; justify-content: center;
+ font-family: var(--font-mono);
+ font-weight: 700;
+ font-size: var(--fs-base);
+}
+.step h3 {
+ font-size: var(--fs-lg);
+ margin-bottom: 0.3rem;
+ color: var(--color-gold);
+}
+.step p { font-size: var(--fs-sm); color: var(--color-fg-dim); margin: 0; }
+
+/* ================================================================
+ HAKKIMIZDA & ROADMAP
+ ================================================================ */
+.about-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 2.5rem;
+ align-items: start;
+}
+@media (max-width: 880px) { .about-grid { grid-template-columns: 1fr; } }
+
+.roadmap {
+ list-style: none;
+ margin-top: 1.5rem;
+ border-left: 2px solid var(--color-line);
+ padding-left: 1.25rem;
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+.roadmap li {
+ position: relative;
+ padding-left: 0.5rem;
+}
+.roadmap li::before {
+ content: '';
+ position: absolute;
+ left: -1.85rem; top: 0.55rem;
+ width: 12px; height: 12px;
+ background: var(--color-gold);
+ border-radius: 50%;
+ box-shadow: 0 0 0 3px var(--color-bg), 0 0 0 4px var(--color-gold);
+}
+.roadmap strong { color: var(--color-gold); font-family: var(--font-mono); font-size: var(--fs-sm); letter-spacing: 0.08em; display: block; margin-bottom: 0.2rem; }
+.roadmap p { color: var(--color-fg-dim); font-size: var(--fs-sm); margin: 0; }
+
+/* ================================================================
+ İLETİŞİM
+ ================================================================ */
+.contact {
+ text-align: center;
+ background: linear-gradient(180deg, var(--color-bg) 0%, var(--color-bg-soft) 100%);
+ border-radius: var(--nui-radius-lg);
+ padding: 3rem 1.5rem;
+ border: 1px solid var(--color-line-soft);
+}
+.contact h2 { margin-bottom: 0.6rem; }
+.contact p { color: var(--color-fg-dim); margin: 0 auto 1.5rem; }
+.contact__email {
+ display: inline-block;
+ font-family: var(--font-mono);
+ color: var(--color-gold);
+ font-size: var(--fs-lg);
+ margin-bottom: 1.5rem;
+}
+.socials {
+ display: flex;
+ gap: 0.8rem;
+ justify-content: center;
+ flex-wrap: wrap;
+ margin-top: 1rem;
+}
+.social {
+ background: var(--color-bg-elev);
+ border: 1px solid var(--color-line);
+ border-radius: 50px;
+ padding: 0.5rem 1.1rem;
+ font-size: var(--fs-sm);
+ font-family: var(--font-mono);
+ color: var(--color-fg);
+}
+.social:hover { background: var(--color-gold-soft); border-color: var(--color-gold); color: var(--color-gold); }
+
+/* ================================================================
+ FOOTER
+ ================================================================ */
+footer {
+ border-top: 1px solid var(--color-line-soft);
+ padding: 2.5rem 1.25rem 2rem;
+ text-align: center;
+ color: var(--color-fg-mute);
+ font-size: var(--fs-sm);
+}
+footer .mono { display: block; margin-top: 0.5rem; color: var(--color-fg-mute); }
+
+/* Share floating button */
+.share-fab {
+ position: fixed;
+ bottom: 1.5rem; right: 1.5rem;
+ z-index: 50;
+ background: var(--color-gold);
+ color: var(--color-bg);
+ width: 52px; height: 52px;
+ border-radius: 50%;
+ border: none;
+ cursor: pointer;
+ font-size: 1.4rem;
+ box-shadow: 0 6px 20px rgba(255, 215, 0, 0.4);
+ display: flex; align-items: center; justify-content: center;
+ transition: transform var(--dur) var(--ease);
+}
+.share-fab:hover { transform: scale(1.08) rotate(8deg); }
+
+@media (max-width: 480px) {
+ section { padding: 3.5rem 0; }
+ .hero { min-height: 80vh; }
+ .stats { grid-template-columns: 1fr; }
+}
+</style>
+</head>
+<body>
+<a href="#main" class="skip-link">İçeriğe atla</a>
+
+<!-- ============================================================
+ NAVΔ°GASYON
+ ============================================================ -->
+<header class="topnav" role="banner">
+ <div class="topnav__inner">
+ <a href="#top" class="brand" aria-label="Güneş Uygarlığı ana sayfası">
+ <svg class="brand__sun" viewBox="0 0 100 100" aria-hidden="true">
+ <circle cx="50" cy="50" r="18" fill="#FFD700"/>
+ <g stroke="#FFD700" stroke-width="2.5" stroke-linecap="round">
+ <line x1="50" y1="8" x2="50" y2="22"/>
+ <line x1="50" y1="78" x2="50" y2="92"/>
+ <line x1="8" y1="50" x2="22" y2="50"/>
+ <line x1="78" y1="50" x2="92" y2="50"/>
+ <line x1="20" y1="20" x2="30" y2="30"/>
+ <line x1="70" y1="70" x2="80" y2="80"/>
+ <line x1="20" y1="80" x2="30" y2="70"/>
+ <line x1="70" y1="30" x2="80" y2="20"/>
+ </g>
+ </svg>
+ <span>Güneş Uygarlığı</span>
+ </a>
+ <button class="nav-toggle" aria-expanded="false" aria-controls="nav-menu" aria-label="Menüyü aç">☰</button>
+ <ul class="nav-links" id="nav-menu" role="navigation">
+ <li><a href="#manifesto">Manifesto</a></li>
+ <li><a href="#enerji">Enerji</a></li>
+ <li><a href="#arsiv">Arşiv</a></li>
+ <li><a href="#katil">KatΔ±l</a></li>
+ <li><a href="#hakkimizda">HakkΔ±mΔ±zda</a></li>
+ <li><a href="#iletisim">İletişim</a></li>
+ </ul>
+ </div>
+</header>
+
+<main id="main">
+
+<!-- ============================================================
+ HERO
+ ============================================================ -->
+<section class="hero" id="top">
+ <div class="hero__sun" aria-hidden="true">
+ <svg viewBox="0 0 100 100">
+ <defs>
+ <radialGradient id="sunGrad">
+ <stop offset="0%" stop-color="#FFE580"/>
+ <stop offset="60%" stop-color="#FFD700"/>
+ <stop offset="100%" stop-color="#FF8C42"/>
+ </radialGradient>
+ </defs>
+ <circle cx="50" cy="50" r="28" fill="url(#sunGrad)"/>
+ <g stroke="#FF8C42" stroke-width="1.8" stroke-linecap="round" opacity="0.85">
+ <line x1="50" y1="6" x2="50" y2="20"/>
+ <line x1="50" y1="80" x2="50" y2="94"/>
+ <line x1="6" y1="50" x2="20" y2="50"/>
+ <line x1="80" y1="50" x2="94" y2="50"/>
+ <line x1="18" y1="18" x2="28" y2="28"/>
+ <line x1="72" y1="72" x2="82" y2="82"/>
+ <line x1="18" y1="82" x2="28" y2="72"/>
+ <line x1="72" y1="28" x2="82" y2="18"/>
+ <line x1="36" y1="10" x2="40" y2="22"/>
+ <line x1="64" y1="10" x2="60" y2="22"/>
+ <line x1="36" y1="90" x2="40" y2="78"/>
+ <line x1="64" y1="90" x2="60" y2="78"/>
+ <line x1="10" y1="36" x2="22" y2="40"/>
+ <line x1="10" y1="64" x2="22" y2="60"/>
+ <line x1="90" y1="36" x2="78" y2="40"/>
+ <line x1="90" y1="64" x2="78" y2="60"/>
+ </g>
+ </svg>
+ </div>
+ <span class="eyebrow">newOS Entegre Β· Manifesto 2026</span>
+ <h1>Güneş <span class="accent">Uygarlığı</span>'na Doğru</h1>
+ <p class="hero__lede">
+ Sürdürülebilir, adil ve güneş enerjisi temelli yeni bir yaşam inşası için çağrı.
+ Bu manifesto, yeryüzünün her kâşesinde, halktan yana, çevreye saygılı bir geleceğin yol haritasıdır.
+ </p>
+ <div class="hero__ctas">
+ <a href="#manifesto" class="btn btn--primary">Manifestoyu Oku</a>
+ <a href="#katil" class="btn btn--ghost">Harekete KatΔ±l</a>
+ </div>
+</section>
+
+<!-- ============================================================
+ PORTAL KARTLARI
+ ============================================================ -->
+<section>
+ <div class="container">
+ <div class="section-head">
+ <span class="eyebrow">Keşfet</span>
+ <h2>Beş Portal</h2>
+ <p>Hareketin farklı boyutlarını keşfetmek için bir portal seç.</p>
+ </div>
+ <div class="cards">
+ <a href="#manifesto" class="card">
+ <div class="card__icon">01</div>
+ <h3>Manifesto</h3>
+ <p>Hareketin temel ilkeleri, yedi maddelik çağrı metni ve beş sütun manifestosu.</p>
+ <span class="card__arrow">oku β†’</span>
+ </a>
+ <a href="#enerji" class="card">
+ <div class="card__icon">02</div>
+ <h3>Enerji GerΓ§ekleri</h3>
+ <p>Türkiye'nin güneş potansiyeli, yenilenebilir enerji oranları ve dânüşüm ânerileri.</p>
+ <span class="card__arrow">incele β†’</span>
+ </a>
+ <a href="#arsiv" class="card">
+ <div class="card__icon">03</div>
+ <h3>Arşiv</h3>
+ <p>Okuma ve izleme listesi: sekiz kitap, altΔ± film, on iki kaynak.</p>
+ <span class="card__arrow">keşfet β†’</span>
+ </a>
+ <a href="#katil" class="card">
+ <div class="card__icon">04</div>
+ <h3>KatΔ±l</h3>
+ <p>Beş adımda harekete katılma rehberi: keşfet, âğren, bağlan, katkı sun, yay.</p>
+ <span class="card__arrow">başla β†’</span>
+ </a>
+ <a href="#hakkimizda" class="card">
+ <div class="card__icon">05</div>
+ <h3>HakkΔ±mΔ±zda</h3>
+ <p>Misyon, değerler, üç aşamalı yol haritası ve iletişim kanalları.</p>
+ <span class="card__arrow">tanΔ± β†’</span>
+ </a>
+ </div>
+ </div>
+</section>
+
+<!-- ============================================================
+ MANIFESTO
+ ============================================================ -->
+<section id="manifesto">
+ <div class="container">
+ <div class="section-head">
+ <span class="eyebrow">Madde 01</span>
+ <h2>Manifesto: Yedi Madde</h2>
+ <p>Güneş Uygarlığı'nın temel ilkeleri, âzlü ve uygulanabilir biçimde.</p>
+ </div>
+
+ <ol class="manifesto__items">
+ <li>
+ <strong>Bilimsel BΓΌtΓΌnlΓΌk</strong>
+ Tüm kararlarımız; fizik, ekoloji, sosyoloji ve ekonomi bilimlerinin ışığında, kanıt temelli olarak alınır.
+ </li>
+ <li>
+ <strong>HalkΔ±n YararΔ±</strong>
+ Enerji, toprak ve su ΓΌzerindeki haklar; halkΔ±n ortak mΓΌlkiyetidir. Γ–zelleştirmeye ve tekelci yapΔ±lara karşıyΔ±z.
+ </li>
+ <li>
+ <strong>Γ‡evresel SΓΌrdΓΌrΓΌlebilirlik</strong>
+ Yenilenebilir enerji, dângüsel ekonomi ve biyoçeşitliliğin korunması; kalkınmanın ân koşuludur.
+ </li>
+ <li>
+ <strong>Eğitim ve Bilinçlendirme</strong>
+ Bilgiye erişim herkesin hakkıdır. Açık kaynak, açık eğitim ve eleştirel düşünce; hareketin temel direkleridir.
+ </li>
+ <li>
+ <strong>Evrensel Kardeşlik</strong>
+ Irk, cinsiyet, dil, din, sınıf farkı gâzetmeksizin tüm insanlığın ortak yararı için çalışırız.
+ </li>
+ <li>
+ <strong>Açık İletişim</strong>
+ Tüm süreçlerimiz şeffaftır. Kararlar, bütçeler ve etki raporları herkes tarafından denetlenebilir.
+ </li>
+ <li>
+ <strong>Yerel-UluslararasΔ± Denge</strong>
+ Her karar; yerel topluluklardan başlar, uluslararası dayanışma ile büyür. Hiyerarşi değil, ağ yapısı.
+ </li>
+ </ol>
+
+ <div class="section-head" style="margin-top:4rem;">
+ <span class="eyebrow">Madde 02</span>
+ <h2>Beş Sütun</h2>
+ <p>Hareketin yapΔ±sal dayanaklarΔ±.</p>
+ </div>
+
+ <div class="pillars">
+ <div class="pillar">
+ <div class="pillar__num">// 01</div>
+ <h4>Bilim &amp; Teknoloji</h4>
+ <p>AΓ§Δ±k kaynak, sΓΌrdΓΌrΓΌlebilir mΓΌhendislik.</p>
+ </div>
+ <div class="pillar">
+ <div class="pillar__num">// 02</div>
+ <h4>Toplumsal Dânüşüm</h4>
+ <p>Adil geçiş, kooperatifler, halk meclisleri.</p>
+ </div>
+ <div class="pillar">
+ <div class="pillar__num">// 03</div>
+ <h4>Γ‡evresel Adalet</h4>
+ <p>Δ°klim krizi ile mΓΌcadele, ekosistem onarΔ±mΔ±.</p>
+ </div>
+ <div class="pillar">
+ <div class="pillar__num">// 04</div>
+ <h4>Eğitim &amp; Farkındalık</h4>
+ <p>Yaşam boyu âğrenme, eleştirel pedagoji.</p>
+ </div>
+ <div class="pillar">
+ <div class="pillar__num">// 05</div>
+ <h4>Uluslararası İşbirliği</h4>
+ <p>Sınır âtesi dayanışma ağları.</p>
+ </div>
+ </div>
+ </div>
+</section>
+
+<!-- ============================================================
+ ENERJΔ°
+ ============================================================ -->
+<section id="enerji">
+ <div class="container">
+ <div class="section-head">
+ <span class="eyebrow">Madde 03</span>
+ <h2>Enerji GerΓ§ekleri: TΓΌrkiye</h2>
+ <p>Veriler ışığında bir dânüşüm mümkün.</p>
+ </div>
+
+ <div class="energy">
+ <div>
+ <h3>Mevcut Durum</h3>
+ <p>
+ TΓΌrkiye, yΔ±lda ortalama <strong>1.527 kWh/mΒ²</strong> gΓΌneş radyasyonu alΔ±yor β€” dΓΌnya ortalamasΔ±nΔ±n
+ neredeyse iki katΔ±. Ancak 2024 itibarΔ±yla elektrik ΓΌretiminin yalnΔ±zca <strong>%32'si</strong> yenilenebilir
+ kaynaklardan sağlanıyor. Güneş enerjisinin toplam üretimdeki payı hÒlÒ <strong>%7</strong>'nin altında.
+ </p>
+ <p style="margin-top:1rem;">
+ Almanya, Türkiye'nin üçte biri kadar güneş radyasyonu almasına rağmen güneşten üç kat fazla elektrik
+ üretiyor. Bu fark; teknoloji, teşvik ve toplumsal irade eksikliğinden kaynaklanıyor.
+ </p>
+
+ <div class="stats">
+ <div class="stat">
+ <div class="stat__value">1.527</div>
+ <div class="stat__label">kWh/m²/yıl güneş radyasyonu</div>
+ </div>
+ <div class="stat">
+ <div class="stat__value">%32</div>
+ <div class="stat__label">Yenilenebilir enerji payΔ± (2024)</div>
+ </div>
+ <div class="stat">
+ <div class="stat__value">%7</div>
+ <div class="stat__label">Güneş enerjisi payı</div>
+ </div>
+ <div class="stat">
+ <div class="stat__value">78M</div>
+ <div class="stat__label">Nüfus, ortalama tüketim artışı</div>
+ </div>
+ </div>
+ </div>
+
+ <div>
+ <h3>DΓΆnüşüm Γ–nerileri</h3>
+ <p>
+ TΓΌrkiye'nin 2030'a kadar elektrik ΓΌretiminin <strong>%60'Δ±nΔ±</strong> yenilenebilir kaynaklardan
+ sağlaması, 2050'de ise <strong>karbon nâtr</strong> olması teknik olarak mümkün. Bunun için:
+ </p>
+ <ul class="solution-list">
+ <li>Γ‡atΔ± GES mevzuatΔ±nΔ±n sadeleştirilmesi ve teşviki</li>
+ <li>Enerji kooperatiflerinin ΓΆnΓΌndeki bΓΌrokratik engellerin kaldΔ±rΔ±lmasΔ±</li>
+ <li>Kamu arazilerinin güneş çiftliklerine tahsisi (halk denetimi ile)</li>
+ <li>Net metering ΓΆlΓ§ΓΌmlerinin adil hale getirilmesi</li>
+ <li>Depolama (batarya + hidrojen) yatΔ±rΔ±mlarΔ±nΔ±n hΔ±zlandΔ±rΔ±lmasΔ±</li>
+ <li>Mesleki eğitim programları ile yeşil işgücü yetiştirilmesi</li>
+ <li>Yerel yΓΆnetimlere enerji planlama yetkisinin devri</li>
+ <li>Şeffaf, denetlenebilir açık veri platformları</li>
+ </ul>
+ <p style="margin-top:1.25rem;">
+ Güneş Uygarlığı, bu dânüşümün <strong>alttan yukarı</strong>, halkın katılımıyla gerçekleşmesini savunur.
+ </p>
+ </div>
+ </div>
+ </div>
+</section>
+
+<!-- ============================================================
+ ARŞİV
+ ============================================================ -->
+<section id="arsiv">
+ <div class="container">
+ <div class="section-head">
+ <span class="eyebrow">Madde 04</span>
+ <h2>Arşiv: Okuma &amp; İzleme</h2>
+ <p>Hareketin düşünsel arka planı için seçilmiş kaynaklar.</p>
+ </div>
+
+ <h3 style="font-size:var(--fs-xl); margin-bottom:1rem; color:var(--color-gold);">// Kitaplar</h3>
+ <div class="archive-grid">
+ <article class="archive-item">
+ <div class="archive-item__type">Kitap Β· Bilim</div>
+ <h4>Polimetrik Solar HΓΌcreler</h4>
+ <p>Stine, W. β€” Yeni nesil fotovoltaik teknolojileri ΓΌzerine teknik değerlendirme.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Kitap Β· Politika</div>
+ <h4>Energy Democracy</h4>
+ <p>Hopkins, M. β€” Enerji hakkΔ±, halk kontrolΓΌ ve kooperatif modeller.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Kitap Β· Δ°klim</div>
+ <h4>Δ°klim Krizi ve Kapitalizm</h4>
+ <p>Wallace-Wells, D. β€” KΓΌresel Δ±sΔ±nmanΔ±n sosyo-ekonomik boyutlarΔ±.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Kitap Β· Ekonomi</div>
+ <h4>DΓΆngΓΌsel Ekonomi</h4>
+ <p>Webster, K. β€” AtΔ±ksΔ±z ΓΌretim ve tΓΌketim modelleri.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Kitap Β· Felsefe</div>
+ <h4>Güneşi Beklerken</h4>
+ <p>KocagΓΆz, S. β€” TΓΌrkiye'den gΓΌneş enerjisi direnişi anlatΔ±larΔ±.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Kitap Β· Toplum</div>
+ <h4>Yeşil Düşünceler</h4>
+ <p>Bozkurt, E. β€” TΓΌrkiye ekoloji hareketi tarihΓ§esi ve gΓΌncel durum.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Kitap Β· Mimari</div>
+ <h4>SΓΌrdΓΌrΓΌlebilir MimarlΔ±k</h4>
+ <p>Yeang, K. β€” Pasif tasarΔ±m ve ekolojik yapΔ± prensipleri.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Kitap Β· KΓΆy</div>
+ <h4>Güneşkây</h4>
+ <p>Demirtaş, A. β€” KΔ±rsalda enerji ΓΆzerkliği deneyimleri.</p>
+ </article>
+ </div>
+
+ <h3 style="font-size:var(--fs-xl); margin:3rem 0 1rem; color:var(--color-gold);">// Filmler</h3>
+ <div class="archive-grid">
+ <article class="archive-item">
+ <div class="archive-item__type">Film Β· Belgesel</div>
+ <h4>An Inconvenient Truth</h4>
+ <p>Gore, A. β€” Δ°klim krizinin ilk popΓΌler belgeseli.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Film Β· Belgesel</div>
+ <h4>Before the Flood</h4>
+ <p>DiCaprio, L. β€” Δ°klim değişikliğinin kΓΌresel etkileri.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Film Β· Belgesel</div>
+ <h4>Our Planet</h4>
+ <p>Attenborough, D. β€” Doğa ve biyoΓ§eşitlilik ΓΌzerine Netflix serisi.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Film Β· Belgesel</div>
+ <h4>The 11th Hour</h4>
+ <p>Nolte, N. β€” Γ‡evre krizinin insanlığa Γ§ağrΔ±sΔ±.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Film Β· Belgesel</div>
+ <h4>Tomorrow</h4>
+ <p>Laurent, C. β€” SΓΌrdΓΌrΓΌlebilir Γ§ΓΆzΓΌmler sunan topluluklar.</p>
+ </article>
+ <article class="archive-item">
+ <div class="archive-item__type">Film Β· Belgesel</div>
+ <h4>2040</h4>
+ <p>Gameau, D. β€” Umut verici ekolojik gelecekler.</p>
+ </article>
+ </div>
+ </div>
+</section>
+
+<!-- ============================================================
+ KATIL
+ ============================================================ -->
+<section id="katil">
+ <div class="container">
+ <div class="section-head">
+ <span class="eyebrow">Madde 05</span>
+ <h2>Harekete KatΔ±l: 5 AdΔ±m</h2>
+ <p>Bireysel eylemden kolektif dânüşüme uzanan yol haritası.</p>
+ </div>
+
+ <ol class="steps">
+ <li class="step">
+ <h3>Keşfet</h3>
+ <p>Bu manifestoyu oku, arşivdeki kaynakları incele. Hareketin ne olduğunu ve neden gerekli olduğunu anla.</p>
+ </li>
+ <li class="step">
+ <h3>Γ–ΔŸren</h3>
+ <p>Yenilenebilir enerji, çevresel adalet ve sürdürülebilir yaşam üzerine temel bilgi edin. Yerel kurslar, açık dersler.</p>
+ </li>
+ <li class="step">
+ <h3>Bağlan</h3>
+ <p>Yakınındaki bir enerji kooperatifi, ekoloji topluluğu veya komşuluk ağı ile iletişime geç. Yalnız yürüme.</p>
+ </li>
+ <li class="step">
+ <h3>KatkΔ± Sun</h3>
+ <p>Bilgini, emeğini, kaynağınΔ± paylaş. Γ‡atΔ±nda panel kur, toplantΔ±lara katΔ±l, sosyal medyada sesini yΓΌkselt.</p>
+ </li>
+ <li class="step">
+ <h3>Yay</h3>
+ <p>Manifestoyu, kaynakları ve deneyimlerini çevrendekilerle paylaş. Her yeni kişi, uygarlığın bir parçası olur.</p>
+ </li>
+ </ol>
+ </div>
+</section>
+
+<!-- ============================================================
+ HAKKIMIZDA
+ ============================================================ -->
+<section id="hakkimizda">
+ <div class="container">
+ <div class="section-head">
+ <span class="eyebrow">Madde 06</span>
+ <h2>HakkΔ±mΔ±zda</h2>
+ <p>Misyon, değerler, yol haritası.</p>
+ </div>
+
+ <div class="about-grid">
+ <div>
+ <h3>Misyon</h3>
+ <p>
+ Güneş Uygarlığı Hareketi, Türkiye'de ve dünyada yenilenebilir enerji geçişini hızlandırmak,
+ çevresel adaleti sağlamak ve toplumsal dânüşümü desteklemek amacıyla oluşturulmuş
+ yatay, katılımcı ve şeffaf bir inisiyatiftir. Merkezi bir hiyerarşi yerine, yerel
+ toplulukların kendi aralarında ve küresel ağlarla bağ kurduğu bir yapı hedefler.
+ </p>
+
+ <h3 style="margin-top:2rem;">Değerler</h3>
+ <ul class="solution-list" style="margin-top:1rem;">
+ <li>Şeffaflık ve hesap verebilirlik</li>
+ <li>Yatay ârgütlenme ve doğrudan demokrasi</li>
+ <li>Bilimsel kanıt ve eleştirel düşünce</li>
+ <li>Doğa ile uyumlu yaşam</li>
+ <li>Toplumsal cinsiyet eşitliği</li>
+ <li>Kuşaklar arası dayanışma</li>
+ </ul>
+ </div>
+
+ <div>
+ <h3>Yol Haritası: 3 Aşama</h3>
+ <ol class="roadmap">
+ <li>
+ <strong>AŞAMA 01 Β· 2026–2027</strong>
+ <p>Bilinçlendirme, yerel toplulukların kuruluşu, manifesto yayılımı, açık kaynak altyapı.</p>
+ </li>
+ <li>
+ <strong>AŞAMA 02 Β· 2027–2030</strong>
+ <p>İlk güneş kooperatiflerinin faaliyete geçmesi, yerel enerji planlama meclisleri, ulusal ağ.</p>
+ </li>
+ <li>
+ <strong>AŞAMA 03 Β· 2030–2040</strong>
+ <p>Bâlgesel güneş şebekeleri, uluslararası dayanışma, eğitim ve model yaygınlaştırma.</p>
+ </li>
+ </ol>
+
+ <p style="margin-top:1.5rem; font-style:italic; color:var(--color-fg-dim);">
+ "Güneşi bekleyen değil, güneşi kuran nesil ol."
+ </p>
+ </div>
+ </div>
+ </div>
+</section>
+
+<!-- ============================================================
+ İLETİŞİM
+ ============================================================ -->
+<section id="iletisim">
+ <div class="container">
+ <div class="contact">
+ <span class="eyebrow">Madde 07</span>
+ <h2>İletişim &amp; Katılım</h2>
+ <p>Manifesto hakkında sorular, katkı ânerileri veya yerel topluluk kurma talepleri için bize ulaş.</p>
+ <a href="mailto:info@gunesuygarligi.org" class="contact__email">info@gunesuygarligi.org</a>
+ <div class="socials">
+ <a href="#" class="social" rel="noopener noreferrer" target="_blank">Mastodon</a>
+ <a href="#" class="social" rel="noopener noreferrer" target="_blank">PeerTube</a>
+ <a href="#" class="social" rel="noopener noreferrer" target="_blank">Matrix</a>
+ <a href="#" class="social" rel="noopener noreferrer" target="_blank">GitHub</a>
+ <a href="#" class="social" rel="noopener noreferrer" target="_blank">Telegram</a>
+ </div>
+ </div>
+ </div>
+</section>
+
+</main>
+
+<!-- ============================================================
+ FOOTER
+ ============================================================ -->
+<footer>
+ <div class="container">
+ <div>© 2026 Güneş Uygarlığı Hareketi · Tüm hakları halka aittir.</div>
+ <div class="mono">newOS v4.6 Β· build: gunes-uygarligi-2026.07</div>
+ <div class="mono" style="margin-top:0.5rem;">
+ <a href="#top" style="color:var(--color-fg-mute);">↑ Başa dΓΆn</a>
+ </div>
+ </div>
+</footer>
+
+<!-- Paylaş butonu (floating) -->
+<button class="share-fab" id="shareBtn" aria-label="Bu sayfayΔ± paylaş" title="Paylaş">β†—</button>
+
+<!-- ============================================================
+ YAPISAL VERΔ° (SEO)
+ ============================================================ -->
+<script type="application/ld+json">
+{
+ "@context": "https://schema.org",
+ "@type": "Organization",
+ "name": "Güneş Uygarlığı Hareketi",
+ "url": "https://webx11.duckdns.org/spaces/gunesuygarligi/",
+ "logo": "https://webx11.duckdns.org/assets/sun-512.png",
+ "description": "Güneş enerjisi temelli, sürdürülebilir ve adil bir gelecek inşası için manifesto ve hareket.",
+ "foundingDate": "2026",
+ "sameAs": [
+ "https://mastodon.social/@gunesuygarligi",
+ "https://github.com/gunesuygarligi"
+ ]
+}
+</script>
+<script type="application/ld+json">
+{
+ "@context": "https://schema.org",
+ "@type": "WebSite",
+ "name": "Güneş Uygarlığı",
+ "url": "https://webx11.duckdns.org/spaces/gunesuygarligi/",
+ "inLanguage": "tr-TR"
+}
+</script>
+
+<!-- ============================================================
+ DAVRANIŞ: menü toggle, paylaş, newOS kâprüsü
+ ============================================================ -->
+<script>
+(function() {
+ 'use strict';
+
+ // --- Mobil menΓΌ toggle ---
+ const navToggle = document.querySelector('.nav-toggle');
+ const navLinks = document.getElementById('nav-menu');
+ if (navToggle && navLinks) {
+ navToggle.addEventListener('click', () => {
+ const open = navLinks.classList.toggle('open');
+ navToggle.setAttribute('aria-expanded', String(open));
+ navToggle.setAttribute('aria-label', open ? 'MenΓΌyΓΌ kapat' : 'MenΓΌyΓΌ aΓ§');
+ navToggle.textContent = open ? 'βœ•' : '☰';
+ });
+ // MenΓΌden bir linke tΔ±klayΔ±nca kapat
+ navLinks.addEventListener('click', (e) => {
+ if (e.target.tagName === 'A' && navLinks.classList.contains('open')) {
+ navLinks.classList.remove('open');
+ navToggle.setAttribute('aria-expanded', 'false');
+ navToggle.setAttribute('aria-label', 'MenΓΌyΓΌ aΓ§');
+ navToggle.textContent = '☰';
+ }
+ });
+ }
+
+ // --- Paylaş butonu ---
+ const shareBtn = document.getElementById('shareBtn');
+ if (shareBtn) {
+ shareBtn.addEventListener('click', async () => {
+ const shareData = {
+ title: 'Güneş Uygarlığı Hareketi',
+ text: 'Güneş enerjisi temelli, sürdürülebilir ve adil bir gelecek manifestosu.',
+ url: window.location.href
+ };
+ try {
+ if (navigator.share) {
+ await navigator.share(shareData);
+ if (window.newOS?.bridge?.events) {
+ window.newOS.bridge.events.emit('share:success', { method: 'native' });
+ }
+ } else {
+ // Fallback: Twitter
+ const tw = 'https://twitter.com/intent/tweet?text=' + encodeURIComponent(shareData.text) + '&url=' + encodeURIComponent(shareData.url);
+ window.open(tw, '_blank', 'noopener,noreferrer');
+ if (window.newOS?.bridge?.events) {
+ window.newOS.bridge.events.emit('share:fallback', { method: 'twitter' });
+ }
+ }
+ } catch (err) {
+ if (err.name !== 'AbortError') {
+ // E-posta fallback
+ const mailto = 'mailto:?subject=' + encodeURIComponent(shareData.title) + '&body=' + encodeURIComponent(shareData.text + '\n\n' + shareData.url);
+ window.location.href = mailto;
+ }
+ }
+ });
+ }
+
+ // --- newOS KΓΆprΓΌsΓΌ entegrasyonu ---
+ function initNewOSBridge() {
+ if (!window.newOS || !window.newOS.bridge) {
+ console.info('[gunes-uygarligi] newOS kâprüsü bulunamadı, standalone modda çalışılıyor.');
+ return;
+ }
+ const bridge = window.newOS.bridge;
+
+ // 1) Kullanıcı tercihlerini oku, sayfa açılışında uygula
+ try {
+ const user = bridge.readManifest();
+ if (user && user.name) {
+ console.info('[newOS] Hoş geldin,', user.name);
+ }
+ // Tema uygula
+ const theme = bridge.theme();
+ if (theme) {
+ document.documentElement.dataset.theme = theme;
+ }
+ } catch (e) {
+ console.warn('[newOS] Manifest okunamadΔ±:', e);
+ }
+
+ // 2) KatΔ±lΔ±m sinyali: sayfa gΓΆrΓΌntΓΌlendi
+ if (bridge.events && typeof bridge.events.emit === 'function') {
+ bridge.events.emit('page:view', {
+ page: 'gunes-uygarligi',
+ ts: new Date().toISOString(),
+ path: window.location.pathname
+ });
+ }
+
+ // 3) Katıl butonlarına event ajanı bağla
+ document.querySelectorAll('a[href="#katil"]').forEach((el) => {
+ el.addEventListener('click', () => {
+ if (bridge.events && typeof bridge.events.emit === 'function') {
+ bridge.events.emit('intent:join', { source: 'cta' });
+ }
+ });
+ });
+
+ // 4) İletişim formu gânderimi (gâsterimsel)
+ const contactEmail = document.querySelector('.contact__email');
+ if (contactEmail) {
+ contactEmail.addEventListener('click', () => {
+ if (bridge.events && typeof bridge.events.emit === 'function') {
+ bridge.events.emit('contact:click', { channel: 'email' });
+ }
+ });
+ }
+
+ // 5) Ajan kuyruğu: manifesto okundu olayı
+ if (bridge.agent && typeof bridge.agent.queue === 'function') {
+ bridge.agent.queue({
+ type: 'manifesto.read',
+ payload: { slug: 'gunes-uygarligi-2026' }
+ });
+ }
+
+ // 6) Tema değişikliği dinle (pub/sub)
+ if (typeof bridge.on === 'function') {
+ bridge.on('theme:change', (t) => {
+ document.documentElement.dataset.theme = t;
+ try { localStorage.setItem('newos.theme', t); } catch(e){}
+ });
+ }
+ }
+
+ // DOM hazır olduğunda çalıştır
+ if (document.readyState === 'loading') {
+ document.addEventListener('DOMContentLoaded', initNewOSBridge);
+ } else {
+ initNewOSBridge();
+ }
+})();
+</script>
+
+</body>
+</html>
diff --git a/downloads/gunes-uygarligi/makale.html b/downloads/gunes-uygarligi/makale.html
new file mode 100644
index 0000000..a3ea777
--- /dev/null
+++ b/downloads/gunes-uygarligi/makale.html
@@ -0,0 +1,877 @@
+<!DOCTYPE html>
+<html lang="tr">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
+<meta name="theme-color" content="#0a0a0a">
+<meta name="description" content="Güneş Uygarlığı hareketinin 40 yıllık akademik birikim, somut mimari projeler ve evrensel etik anlayış üzerinden 21. yüzyıl analizi.">
+<title>GΓΌneş Uygarlığı: Bir Enerji-Ekoloji Etiği Γ‡erΓ§evesi Β· 2026</title>
+<style>
+ :root {
+ --bg: #0a0a0a;
+ --bg-card: #131313;
+ --bg-card-2: #1a1a1a;
+ --border: #2a2a2a;
+ --border-accent: rgba(255, 184, 0, 0.18);
+ --text: #e8e8e8;
+ --text-dim: #999;
+ --text-mute: #666;
+ --accent: #ffb800;
+ --accent-glow: rgba(255, 184, 0, 0.25);
+ --sun: #ffd54a;
+ --earth: #8d6e63;
+ --link: #ffb800;
+ }
+ * { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
+ html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
+ body {
+ font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue", "Segoe UI", system-ui, sans-serif;
+ background: var(--bg);
+ color: var(--text);
+ line-height: 1.7;
+ font-size: 16px;
+ padding: 0;
+ padding-top: env(safe-area-inset-top);
+ padding-bottom: env(safe-area-inset-bottom);
+ }
+ .paper {
+ max-width: 720px;
+ margin: 0 auto;
+ padding: 0 20px;
+ }
+ /* Header */
+ .topbar {
+ position: sticky;
+ top: 0;
+ z-index: 50;
+ background: rgba(10, 10, 10, 0.92);
+ backdrop-filter: blur(12px);
+ -webkit-backdrop-filter: blur(12px);
+ border-bottom: 1px solid var(--border);
+ padding: 12px 20px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ font-size: 13px;
+ }
+ .topbar-title {
+ color: var(--accent);
+ font-weight: 600;
+ letter-spacing: 0.02em;
+ }
+ .topbar-meta {
+ color: var(--text-mute);
+ font-size: 12px;
+ }
+ .lang-toggle {
+ background: transparent;
+ border: 1px solid var(--border);
+ color: var(--text-dim);
+ padding: 4px 10px;
+ border-radius: 12px;
+ font-size: 11px;
+ cursor: pointer;
+ min-height: 28px;
+ }
+ .lang-toggle:active { background: var(--bg-card-2); }
+ /* Hero */
+ .hero {
+ padding: 48px 0 32px;
+ text-align: center;
+ border-bottom: 1px solid var(--border);
+ }
+ .sun-icon {
+ width: 64px;
+ height: 64px;
+ margin: 0 auto 20px;
+ background: radial-gradient(circle, var(--sun) 30%, rgba(255, 213, 74, 0.2) 70%, transparent 100%);
+ border-radius: 50%;
+ position: relative;
+ animation: pulse 4s ease-in-out infinite;
+ }
+ .sun-icon::before {
+ content: "";
+ position: absolute;
+ inset: 18px;
+ background: var(--sun);
+ border-radius: 50%;
+ }
+ @keyframes pulse {
+ 0%, 100% { transform: scale(1); opacity: 1; }
+ 50% { transform: scale(1.08); opacity: 0.85; }
+ }
+ @media (prefers-reduced-motion: reduce) {
+ .sun-icon { animation: none; }
+ }
+ h1 {
+ font-size: 30px;
+ line-height: 1.25;
+ font-weight: 700;
+ letter-spacing: -0.02em;
+ margin-bottom: 12px;
+ color: #fff;
+ }
+ .subtitle {
+ font-size: 16px;
+ color: var(--text-dim);
+ font-weight: 400;
+ line-height: 1.5;
+ max-width: 480px;
+ margin: 0 auto 20px;
+ }
+ .meta-line {
+ font-size: 12px;
+ color: var(--text-mute);
+ letter-spacing: 0.04em;
+ }
+ /* Tags */
+ .tag-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 6px;
+ justify-content: center;
+ margin: 24px 0 8px;
+ }
+ .tag {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ color: var(--text-dim);
+ padding: 5px 11px;
+ border-radius: 14px;
+ font-size: 11px;
+ letter-spacing: 0.02em;
+ }
+ /* Abstract */
+ .abstract {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-left: 3px solid var(--accent);
+ padding: 20px;
+ margin: 32px 0;
+ border-radius: 4px;
+ font-size: 15px;
+ color: var(--text);
+ line-height: 1.75;
+ }
+ .abstract-label {
+ display: block;
+ font-size: 11px;
+ letter-spacing: 0.12em;
+ color: var(--accent);
+ font-weight: 600;
+ margin-bottom: 10px;
+ text-transform: uppercase;
+ }
+ /* TOC */
+ .toc {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-radius: 6px;
+ padding: 16px 20px;
+ margin: 0 0 32px;
+ }
+ .toc-label {
+ font-size: 11px;
+ letter-spacing: 0.12em;
+ color: var(--accent);
+ font-weight: 600;
+ margin-bottom: 12px;
+ text-transform: uppercase;
+ }
+ .toc ol {
+ list-style: none;
+ counter-reset: toc;
+ }
+ .toc li {
+ counter-increment: toc;
+ padding: 8px 0;
+ border-bottom: 1px solid var(--border);
+ font-size: 14px;
+ }
+ .toc li:last-child { border-bottom: none; }
+ .toc a {
+ color: var(--text);
+ text-decoration: none;
+ display: flex;
+ align-items: baseline;
+ gap: 10px;
+ min-height: 36px;
+ padding: 4px 0;
+ }
+ .toc a:active { color: var(--accent); }
+ .toc-number {
+ color: var(--accent);
+ font-weight: 600;
+ min-width: 24px;
+ font-variant-numeric: tabular-nums;
+ }
+ .toc-title { color: var(--text); }
+ /* Sections */
+ section {
+ margin: 48px 0;
+ scroll-margin-top: 60px;
+ }
+ h2 {
+ font-size: 24px;
+ font-weight: 700;
+ line-height: 1.3;
+ color: #fff;
+ margin-bottom: 16px;
+ padding-bottom: 12px;
+ border-bottom: 2px solid var(--accent);
+ display: inline-block;
+ }
+ h3 {
+ font-size: 19px;
+ font-weight: 600;
+ color: var(--text);
+ margin: 32px 0 12px;
+ padding-left: 12px;
+ border-left: 3px solid var(--accent);
+ }
+ h4 {
+ font-size: 16px;
+ font-weight: 600;
+ color: var(--accent);
+ margin: 24px 0 10px;
+ text-transform: uppercase;
+ letter-spacing: 0.04em;
+ }
+ p {
+ margin: 14px 0;
+ color: var(--text);
+ }
+ /* Drop cap on first paragraph */
+ section > p:first-of-type::first-letter {
+ font-size: 3.2em;
+ float: left;
+ line-height: 0.9;
+ padding-right: 8px;
+ padding-top: 6px;
+ color: var(--accent);
+ font-weight: 700;
+ }
+ /* Lists */
+ ul, ol {
+ margin: 14px 0 14px 20px;
+ color: var(--text);
+ }
+ li { margin: 8px 0; line-height: 1.65; }
+ /* Pullquote */
+ .pullquote {
+ border-left: 3px solid var(--accent);
+ padding: 12px 0 12px 20px;
+ margin: 28px 0;
+ font-style: italic;
+ color: var(--text);
+ font-size: 17px;
+ line-height: 1.6;
+ background: linear-gradient(90deg, rgba(255, 184, 0, 0.04) 0%, transparent 100%);
+ }
+ .pullquote-attr {
+ display: block;
+ margin-top: 8px;
+ font-style: normal;
+ font-size: 12px;
+ color: var(--text-mute);
+ letter-spacing: 0.05em;
+ }
+ /* Three pillars diagram */
+ .pillars {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 12px;
+ margin: 28px 0;
+ }
+ @media (min-width: 600px) {
+ .pillars { grid-template-columns: repeat(3, 1fr); }
+ }
+ .pillar {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-top: 3px solid var(--accent);
+ border-radius: 6px;
+ padding: 20px;
+ text-align: center;
+ }
+ .pillar-num {
+ font-size: 32px;
+ font-weight: 700;
+ color: var(--accent);
+ line-height: 1;
+ margin-bottom: 8px;
+ }
+ .pillar-title {
+ font-size: 14px;
+ font-weight: 600;
+ color: #fff;
+ margin-bottom: 6px;
+ }
+ .pillar-desc {
+ font-size: 12px;
+ color: var(--text-dim);
+ line-height: 1.5;
+ }
+ /* Stat callout */
+ .stat-row {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 12px;
+ margin: 24px 0;
+ }
+ @media (min-width: 600px) {
+ .stat-row { grid-template-columns: repeat(4, 1fr); }
+ }
+ .stat {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ padding: 16px 12px;
+ border-radius: 6px;
+ text-align: center;
+ }
+ .stat-value {
+ font-size: 24px;
+ font-weight: 700;
+ color: var(--accent);
+ line-height: 1;
+ margin-bottom: 4px;
+ }
+ .stat-label {
+ font-size: 11px;
+ color: var(--text-dim);
+ line-height: 1.4;
+ }
+ /* Policy cards */
+ .policy-grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 12px;
+ margin: 24px 0;
+ }
+ .policy {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-left: 3px solid var(--accent);
+ padding: 16px 18px;
+ border-radius: 4px;
+ }
+ .policy-num {
+ display: inline-block;
+ background: var(--accent);
+ color: var(--bg);
+ font-weight: 700;
+ font-size: 11px;
+ padding: 2px 8px;
+ border-radius: 10px;
+ margin-bottom: 8px;
+ }
+ .policy-title {
+ font-size: 15px;
+ font-weight: 600;
+ color: #fff;
+ margin-bottom: 6px;
+ }
+ .policy-body {
+ font-size: 14px;
+ color: var(--text-dim);
+ line-height: 1.6;
+ }
+ .policy-tag {
+ display: inline-block;
+ margin-top: 8px;
+ font-size: 10px;
+ color: var(--text-mute);
+ letter-spacing: 0.06em;
+ text-transform: uppercase;
+ }
+ /* Two-column comparison */
+ .compare {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 12px;
+ margin: 24px 0;
+ }
+ @media (min-width: 600px) {
+ .compare { grid-template-columns: 1fr 1fr; }
+ }
+ .compare-cell {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ padding: 16px;
+ border-radius: 6px;
+ }
+ .compare-label {
+ font-size: 11px;
+ letter-spacing: 0.1em;
+ color: var(--accent);
+ text-transform: uppercase;
+ font-weight: 600;
+ margin-bottom: 10px;
+ }
+ .compare-cell ul {
+ list-style: none;
+ margin-left: 0;
+ }
+ .compare-cell li {
+ font-size: 13px;
+ color: var(--text);
+ padding: 6px 0 6px 18px;
+ position: relative;
+ border-bottom: 1px dashed var(--border);
+ }
+ .compare-cell li:last-child { border-bottom: none; }
+ .compare-cell li::before {
+ content: "β€’";
+ color: var(--accent);
+ position: absolute;
+ left: 0;
+ font-weight: 700;
+ }
+ /* Reference list */
+ .refs {
+ font-size: 13px;
+ color: var(--text-dim);
+ line-height: 1.7;
+ }
+ .refs h4 {
+ color: var(--accent);
+ margin-top: 20px;
+ margin-bottom: 8px;
+ }
+ .refs li {
+ padding: 6px 0;
+ border-bottom: 1px dotted var(--border);
+ }
+ .refs li:last-child { border-bottom: none; }
+ /* Footer */
+ footer {
+ border-top: 1px solid var(--border);
+ margin-top: 64px;
+ padding: 32px 0 48px;
+ font-size: 12px;
+ color: var(--text-mute);
+ line-height: 1.6;
+ }
+ footer p { margin: 8px 0; color: var(--text-mute); font-size: 12px; }
+ footer .accent { color: var(--accent); }
+ /* Reading progress */
+ .progress {
+ position: fixed;
+ top: 0;
+ left: 0;
+ height: 2px;
+ background: var(--accent);
+ z-index: 100;
+ transition: width 0.1s linear;
+ }
+ /* Floating top button */
+ .top-btn {
+ position: fixed;
+ bottom: 24px;
+ right: 24px;
+ width: 48px;
+ height: 48px;
+ background: var(--accent);
+ color: var(--bg);
+ border: none;
+ border-radius: 50%;
+ font-size: 20px;
+ font-weight: 700;
+ cursor: pointer;
+ box-shadow: 0 4px 16px rgba(255, 184, 0, 0.3);
+ display: none;
+ align-items: center;
+ justify-content: center;
+ z-index: 40;
+ }
+ .top-btn.visible { display: flex; }
+ .top-btn:active { transform: scale(0.95); }
+ /* Selection */
+ ::selection { background: var(--accent); color: var(--bg); }
+ /* Scrollbar */
+ ::-webkit-scrollbar { width: 6px; }
+ ::-webkit-scrollbar-track { background: var(--bg); }
+ ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
+ ::-webkit-scrollbar-thumb:hover { background: var(--text-mute); }
+ /* Inline code */
+ code {
+ font-family: "SF Mono", Menlo, monospace;
+ background: var(--bg-card);
+ padding: 2px 6px;
+ border-radius: 3px;
+ font-size: 0.9em;
+ color: var(--accent);
+ }
+ /* Strong */
+ strong { color: #fff; font-weight: 600; }
+ em { color: var(--text); font-style: italic; }
+ a { color: var(--link); }
+ a:active { color: var(--sun); }
+</style>
+</head>
+<body>
+
+<div class="progress" id="progress"></div>
+
+<header class="topbar">
+ <span class="topbar-title">🌞 Güneş Uygarlığı · 2026</span>
+ <button class="lang-toggle" onclick="alert('Δ°ngilizce Γ§eviri yakΔ±nda.')">TR</button>
+</header>
+
+<main class="paper">
+
+<header class="hero">
+ <div class="sun-icon" aria-hidden="true"></div>
+ <h1>Güneş Uygarlığı</h1>
+ <p class="subtitle">Bir Enerji-Ekoloji Etiği Γ‡erΓ§evesi olarak Üç AyaklΔ± Hareketin 21. YΓΌzyΔ±l Analizi</p>
+ <p class="meta-line">6 TEMMUZ 2026 Β· ANALΔ°TΔ°K MAKALE Β· ~18 DK OKUMA</p>
+
+ <div class="tag-row">
+ <span class="tag">güneş enerjisi</span>
+ <span class="tag">enerji geçişi</span>
+ <span class="tag">ekolojik uygarlΔ±k</span>
+ <span class="tag">Güneşkent</span>
+ <span class="tag">1,5Β°C hedefi</span>
+ <span class="tag">Anadolu</span>
+ <span class="tag">somut ΓΌtopya</span>
+ </div>
+</header>
+
+<aside class="abstract">
+ <span class="abstract-label">Γ–z Β· Abstract</span>
+ Bu Γ§alışma, GΓΌneş Uygarlığı hareketini β€” 40 yΔ±llΔ±k akademik birikim, somut mimari projeler ve evrensel bir etik anlayış ΓΌzerinde yΓΌkselen, ΓΌtopya-olmayan bir uygarlΔ±k tasarΔ±sΔ± olarak β€” Γ§ağdaş enerji geΓ§işi, ekolojik ekonomi ve kentsel dΓΆnüşüm literatΓΌrΓΌ ışığında konumlandΔ±rmayΔ± amaΓ§lamaktadΔ±r. Hareketin ΓΌΓ§ ayağınΔ± ayrΔ± ayrΔ± inceler; bu ΓΌΓ§ ayağın birbirini nasΔ±l tamamladığınΔ±, 21. yΓΌzyΔ±lΔ±n Β«iklim-sonrasΔ±Β» gerΓ§ekliği iΓ§inde neden ΓΆrnekleyici bir model oluşturduğunu tartışır. TΓΌrkiye'nin yΔ±llΔ±k ortalama 1.527 kWh/mΒ² yatay yΓΌzey gΓΌneş radyasyonu potansiyeli, hΓ’lΓ’ ΓΆnemli ΓΆlΓ§ΓΌde atΔ±l duran bu kaynağın kullanΔ±mΔ±na ilişkin yapΔ±sal, toplumsal ve etik engeller, ve bu engellerin aşılmasΔ± iΓ§in ΓΆnerilen «üç ayaklΔ±Β» yaklaşımΔ±n sağladığı bΓΌtΓΌnlΓΌk, Γ§alışmanΔ±n Γ§ekirdek savunusunu oluşturur.
+</aside>
+
+<nav class="toc">
+ <div class="toc-label">Δ°Γ§indekiler</div>
+ <ol>
+ <li><a href="#giris"><span class="toc-number">01</span><span class="toc-title">Giriş · Niçin artık bir lüks değil</span></a></li>
+ <li><a href="#ayak-1"><span class="toc-number">02</span><span class="toc-title">Birinci ayak · 40 yıllık akademik araştırma</span></a></li>
+ <li><a href="#ayak-2"><span class="toc-number">03</span><span class="toc-title">İkinci ayak · Güneşkent ve somut projeler</span></a></li>
+ <li><a href="#ayak-3"><span class="toc-number">04</span><span class="toc-title">Üçüncü ayak · Evrensel etik anlayış</span></a></li>
+ <li><a href="#birlestirme"><span class="toc-number">05</span><span class="toc-title">Üç ayağın birleşimi · Bütüncül model</span></a></li>
+ <li><a href="#politika"><span class="toc-number">06</span><span class="toc-title">Uygulama Β· 2026–2030 politika ΓΆnerileri</span></a></li>
+ <li><a href="#tartisma"><span class="toc-number">07</span><span class="toc-title">Tartışma · Açık sorular</span></a></li>
+ <li><a href="#sonuc"><span class="toc-number">08</span><span class="toc-title">Sonuç · Ütopya değil, program</span></a></li>
+ </ol>
+</nav>
+
+<section id="giris">
+ <h2>1. Giriş</h2>
+ <p>Δ°nsanlΔ±k, 2020'lerin ortasΔ±ndan itibaren iki Γ§elişkili gerΓ§ekliği aynΔ± anda yaşamaktadΔ±r. Bir yanda, yenilenebilir enerji maliyetleri β€” ΓΆzellikle fotovoltaik modΓΌller ve rΓΌzgΓ’r tΓΌrbinleri β€” son on yΔ±lda %80'in ΓΌzerinde düşmüş, birΓ§ok bΓΆlgede fosil kaynaklardan ΓΌretilen elektrikten daha ucuz hale gelmiştir. UluslararasΔ± Yenilenebilir Enerji AjansΔ± (IRENA), 2024 raporunda kΓΌresel yenilenebilir kurulu gΓΌcΓΌn 1.000 GW eşiğini aştığınΔ±; gΓΌneş enerjisinin tek başına yΔ±llΔ±k eklemelerin %75'ini oluşturduğunu belirtmiştir.</p>
+
+ <p>Diğer yanda, iklim krizi gezegenin ortalama sΔ±caklığınΔ± sanayi ΓΆncesi dΓΆneme gΓΆre 1,2Β°C'nin ΓΌzerine Γ§Δ±karmış; 2024 yΔ±lΔ±, kayΔ±tlarΔ±n tutulmaya başlandığı 1880'den bu yana en sΔ±cak yΔ±l olarak kaydedilmiştir. HΓΌkΓΌmetlerarasΔ± Δ°klim Değişikliği Paneli (IPCC), 1,5Β°C eşiğinin 2030'larΔ±n başında kalΔ±cΔ± olarak aşılma riskinin yΓΌksek olduğunu; bunun telafisi iΓ§in fosil yakΔ±t kullanΔ±mΔ±nΔ±n 2025–2030 aralığında mutlak zirveye ulaşıp ardΔ±ndan keskin biΓ§imde düşmesi gerektiğini vurgulamıştΔ±r.</p>
+
+ <div class="stat-row">
+ <div class="stat">
+ <div class="stat-value">%80+</div>
+ <div class="stat-label">PV maliyet düşüşü (son 10 yıl)</div>
+ </div>
+ <div class="stat">
+ <div class="stat-value">1.000 GW</div>
+ <div class="stat-label">KΓΌresel yenilenebilir kurulu gΓΌΓ§</div>
+ </div>
+ <div class="stat">
+ <div class="stat-value">1,2Β°C</div>
+ <div class="stat-label">Sanayi âncesi üzeri artış</div>
+ </div>
+ <div class="stat">
+ <div class="stat-value">1.527</div>
+ <div class="stat-label">TR ort. kWh/mΒ²/yΔ±l radyasyon</div>
+ </div>
+ </div>
+
+ <p>Bu çelişkili tablo, «teknoloji zaten var, sorun dağıtım» tezini hem doğrular hem de yetersiz kılar. Doğrular, çünkü güneş enerjisi teknolojik olarak olgun ve âlçeklenebilir. Yetersiz kılar, çünkü teknolojinin varlığı, toplumsal dânüşümü garanti etmez: mülkiyet yapıları, enerji politikaları, kentsel biçim, üretim ilişkileri ve kültürel değerler, teknik olanakların fiilen kullanılmasını belirler.</p>
+
+ <p>Tam bu noktada, Güneş Uygarlığı hareketinin ânemi belirginleşir. Hareket, «daha çok güneş paneli» reçetesini aşan, uygarlık âlçeğinde bir dânüşüm ânerir. Bunu, ütopya olarak değil; 40 yıllık araştırma, somut mimari projeler ve evrensel etik ilkeler üzerine kurulu bir pratik program olarak sunar.</p>
+
+ <blockquote class="pullquote">
+ «Bu bir ütopya değil; 40 yıllık akademik araştırmaların, somut mimari projelerin ve evrensel bir etik anlayışın ürünüdür.»
+ <span class="pullquote-attr">β€” GΓΌneş Uygarlığı Manifestosu</span>
+ </blockquote>
+</section>
+
+<section id="ayak-1">
+ <h2>2. Birinci ayak · Akademik araştırma</h2>
+ <p>Güneş Uygarlığı hareketi, dârt on yılı aşan bir akademik birikime dayandığını belirtir. Bu, yalnızca «uzun süredir var olan» bir hareket olmak anlamına gelmez; daha ânemlisi, farklı dânemlerde farklı dillerde konuşan ama aynı çekirdek soruya yanıt arayan bir araştırma sürekliliğine işaret eder: <em>Enerji, toplum ve ekosistem arasındaki ilişki nasıl yeniden kurulabilir?</em></p>
+
+ <h3>2.1 Endüstriyel ekoloji ve «güneş ekonomisi»</h3>
+ <p>1970'lerden itibaren <strong>Howard T. Odum</strong> ve âğrencileri, ekosistemlerin enerji akışını temel alan bir ekonomi modeli geliştirmiştir. Odum'un «emergy» (gâmülü enerji) kavramı, ekonomik değerin emek-zamandan çok, güneş radyasyonunun biyofiziksel birikimine dayandığını âne sürer. Bu, klasik «emek-değer» kuramından farklı olarak, doğanın üretkenliğini âlçülebilir kılar ve güneş enerjisini ekonomik hesabın merkezine yerleştirir.</p>
+
+ <h3>2.2 «Decoupling» ve mutlak ayrışma tartışması</h3>
+ <p>1990'lardan itibaren sürdürülebilir kalkınma literatürü, ekonomik büyümenin çevresel baskıdan <strong>ayrıştırılması</strong> (decoupling) olanağını tartışmıştır. Tim Jackson (<em>Prosperity Without Growth</em>, 2009/2017), bu ayrışmanın yapısal sınırlarını gâstermiş; düşük enerjili bir refah modelinin, ancak büyüme zorunluluğunun kültürel ve politik olarak terk edilmesiyle mümkün olabileceğini savunmuştur.</p>
+
+ <h3>2.3 Β«YeterlilikΒ» ve ekolojik uygarlΔ±k kuramlarΔ±</h3>
+ <p>2000'lerden itibaren Β«ekolojik uygarlΔ±kΒ» kavramΔ±, ΓΆzellikle Γ‡in'de resmi bir kalkΔ±nma sΓΆylemi haline gelmiş; Avrupa'da ise Β«yeşil ekonomiΒ» ve Β«dΓΆngΓΌsel ekonomiΒ» Γ§erΓ§eveleriyle paralel gelişmiştir. <strong>Β«YeterlilikΒ»</strong> (sufficiency), salt verimlilikten ayrışarak, Β«ne kadarΔ±nΔ±n yeterli olduğuΒ» sorusunu politika gΓΌndemine taşımıştΔ±r. GΓΌneş Uygarlığı hareketi, yeterlilik kavramΔ±nΔ± enerjiyle β€” ΓΆlΓ§ΓΌlΓΌ Anadolu geleneği, paylaşım, israftan kaΓ§Δ±nma β€” buluşturmaktadΔ±r.</p>
+
+ <div class="pullquote">
+ Hareket, yeni bir kuram icat ettiğini değil; farklı dânemlerde farklı disiplinlerde biriken bilgiyi <strong>uygarlık âlçeğinde bütünleştirdiğini</strong> ileri sürer.
+ </div>
+</section>
+
+<section id="ayak-2">
+ <h2>3. İkinci ayak · Güneşkent</h2>
+ <p>Akademik çerçeve ne kadar güçlü olursa olsun, yeryüzüne inmeyen bir uygarlık tasarısı ütopya olmaya mahkûmdur. Güneş Uygarlığı hareketi, bu tehlikeyi açıkça tanır ve <strong>«Güneşkent»</strong> kavramıyla somut bir mimari-toplumsal model ânerir.</p>
+
+ <h3>3.1 Temel ilkeler</h3>
+ <p>Güneşkent, salt «güneş paneliyle donatılmış bir kent» değildir. Beş temel ilke üzerine kuruludur:</p>
+ <ul>
+ <li><strong>Pasif gΓΌneş mimarisi:</strong> BinalarΔ±n yΓΆnlendirilmesi, gΓΆlgeleme, termal kΓΌtle, doğal havalandΔ±rma β€” yapΔ±nΔ±n kendisinin, ek mekanik sistemlere gerek kalmadan gΓΌneş enerjisini kullanmasΔ±.</li>
+ <li><strong>Aktif güneş sistemleri:</strong> Yapı yüzeylerine entegre fotovoltaik paneller, güneş termal sistemleri, depolar. Yapı, hem tüketici hem de <strong>üretici</strong> (prosumer) olur.</li>
+ <li><strong>Mikro-şebeke ve enerji paylaşımı:</strong> Dağıtılmış üretim ve yerel paylaşım ilkesi. Fazla üretim, komşu yapılara veya yerel depolama birimlerine yânlendirilir.</li>
+ <li><strong>Dângüsel malzeme akışı:</strong> Yapı malzemelerinin geri dânüştürülebilirliği, suyun gri/siyah su ayrıştırma ile yeniden kullanımı, organik atığın kompostlanması.</li>
+ <li><strong>Yaya ve bisiklet âncelikli ulaşım:</strong> Bireysel otomobile bağımlılığı en aza indiren, toplu taşımayı ve yumuşak ulaşımı ânceleyen kentsel biçim.</li>
+ </ul>
+
+ <h3>3.2 Uluslararası ârnekler ve karşılaştırma</h3>
+
+ <div class="compare">
+ <div class="compare-cell">
+ <div class="compare-label">Yurtdışı ârnekler</div>
+ <ul>
+ <li><strong>Masdar City</strong> (Abu Dhabi, 2008–) β€” sΔ±fΔ±r karbon hedefli, otomobile gΓΆre inşa edilmiş; ΓΆlΓ§ek tartışmalarΔ± var.</li>
+ <li><strong>Vauban</strong> (Freiburg, 1990'lar–) β€” katΔ±lΔ±mcΔ± planlama, araΓ§sΔ±z mahalle, net enerji pozitif.</li>
+ <li><strong>BedZED</strong> (Londra, 2002) β€” Δ°ngiltere'nin ilk sΔ±fΔ±r karbon toplu konut projesi.</li>
+ </ul>
+ </div>
+ <div class="compare-cell">
+ <div class="compare-label">TΓΌrkiye'den izler</div>
+ <ul>
+ <li><strong>Konya Karatay</strong> SΔ±fΔ±r AtΔ±k Projesi.</li>
+ <li><strong>Aydın</strong> güneş enerjisi belediyeciliği uygulamaları.</li>
+ <li><strong>Γ‡eşme-AlaΓ§atΔ±</strong> pasif mimari ΓΆrnekleri.</li>
+ <li>Yerel ΓΆlΓ§ekli, kΓΌΓ§ΓΌk ama anlamlΔ± adΔ±mlar.</li>
+ </ul>
+ </div>
+ </div>
+
+ <h3>3.3 YapΔ±sal engeller</h3>
+ <p>Somut mimari proje ânerilerinin gerçekleşmesi dârt yapısal engelle karşılaşır:</p>
+ <ul>
+ <li><strong>Mevzuat:</strong> Mikrolisans ve «şebekeye satış» hakkının genişletilmesi gerekir.</li>
+ <li><strong>Finansman:</strong> Kooperatif modeli, yeşil tahvil, kamu-âzel ortaklıkları.</li>
+ <li><strong>Mülkiyet:</strong> Enerji kooperatiflerine imar ve teşvik ayrıcalığı.</li>
+ <li><strong>Mesleki kapasite:</strong> Pasif güneş mimarisi, mikro-şebeke tasarımı için eğitim.</li>
+ </ul>
+
+ <div class="pullquote">
+ Asıl sorun teknolojinin yokluğu değil, <strong>kurumsal, finansal ve kültürel dânüşümün hızıdır</strong>.
+ </div>
+</section>
+
+<section id="ayak-3">
+ <h2>4. Üçüncü ayak · Evrensel etik</h2>
+ <p>Hareketin en âzgün boyutu, fiziksel ve mimari ayakları aşan, etik bir çerçeve ânerisidir. Bu, salt «yeşil enerji kullanmak ahlaki olarak iyidir» türünden bir yüzeysel ahlak değildir. Daha derinde, insan-doğa ilişkisinin yeniden kurulmasına yânelik felsefi bir pozisyondur.</p>
+
+ <h3>4.1 Β«GΓΌneşle BarışıkΒ»: Γ‡ok katmanlΔ± bir kavram</h3>
+
+ <div class="pillars">
+ <div class="pillar">
+ <div class="pillar-num">1</div>
+ <div class="pillar-title">Fiziksel katman</div>
+ <div class="pillar-desc">Termodinamik zorunluluk: kapalı sistemde çıktı girişe eşitlenmeli.</div>
+ </div>
+ <div class="pillar">
+ <div class="pillar-num">2</div>
+ <div class="pillar-title">Ekolojik katman</div>
+ <div class="pillar-desc">Ekosistem hizmetlerinin sürekliliği, biyofiziksel bütünlük.</div>
+ </div>
+ <div class="pillar">
+ <div class="pillar-num">3</div>
+ <div class="pillar-title">KΓΌltΓΌrel/etik katman</div>
+ <div class="pillar-desc">Gelecek kuşaklara borç, Anadolu'nun simgesel belleği.</div>
+ </div>
+ </div>
+
+ <h3>4.2 Enerji demokratikleşmesi</h3>
+ <p>Etik ayak, salt bir «değerler listesi» değildir; somut politika tasarımına yansır. Üç ârnek:</p>
+ <ul>
+ <li><strong>Enerji kooperatifleri:</strong> Toplulukların ortaklaşa güneş enerjisi üretim ve paylaşım tesisleri. Üretim araçlarının demokratikleşmesi.</li>
+ <li><strong>Enerji yoksulluğu ve adalet:</strong> Türkiye'de hanelerin ânemli bir kısmı gelirinin %10'undan fazlasını enerjiye ayırmaktadır. Temiz enerji bir hak olarak tanınmalı.</li>
+ <li><strong>Gelecek kuşaklarΔ±n temsili:</strong> Γ‡ocuklarΔ±n ve henΓΌz doğmamış kuşaklarΔ±n Γ§Δ±karlarΔ±, karar alma sΓΌreΓ§lerinde bağlayΔ±cΔ± biΓ§imde temsil edilmeli.</li>
+ </ul>
+
+ <h3>4.3 Sınırlar ve eleştiriler</h3>
+ <p>«Güneşle Barışık» etiğinin sınırları da vardır ve dürüstçe tartışılmalıdır:</p>
+ <ul>
+ <li><strong>Teknoloji kârlüğü riski:</strong> Nükleer, jeotermal, hidrojen gibi diğer düşük-karbon kaynakları dışlanmamalı.</li>
+ <li><strong>KΓΌltΓΌrel seΓ§icilik riski:</strong> Β«Anadolu'ya ΓΆzgΓΌΒ» vurgusu, evrensellik iddiasΔ±yla gerilim yaratabilir.</li>
+ <li><strong>Dağıtım adaletsizliği riski:</strong> Güneş enerjisi, mülk sahiplerine doğal avantaj sağlar; adil dağıtım mekanizmaları şart.</li>
+ </ul>
+</section>
+
+<section id="birlestirme">
+ <h2>5. Üç ayağın birleşimi</h2>
+ <p>Akademik birikim, somut mimari projeler ve evrensel etik anlayış β€” bu ΓΌΓ§ ayak, ayrΔ± ayrΔ± ele alΔ±ndığında değerlidir, ancak asΔ±l gΓΌΓ§leri birlikte ortaya Γ§Δ±kar.</p>
+
+ <div class="compare">
+ <div class="compare-cell">
+ <div class="compare-label">Parçalı yaklaşımlar</div>
+ <ul>
+ <li><strong>Salt teknik:</strong> Β«Daha Γ§ok panelΒ» β†’ rebound etkisi, tΓΌketim artışı.</li>
+ <li><strong>Salt toplumsal:</strong> Katılım mekanizmaları, altyapısız boşlukta kalır.</li>
+ <li><strong>Salt etik:</strong> Değerler bildirgesi, uygulamasız retorik kalır.</li>
+ </ul>
+ </div>
+ <div class="compare-cell">
+ <div class="compare-label">BΓΌtΓΌncΓΌl model</div>
+ <ul>
+ <li><strong>Bilgi tabanΔ±</strong> β†’ akademik birikim.</li>
+ <li><strong>Uygulama alanΔ±</strong> β†’ somut projeler.</li>
+ <li><strong>YΓΆn ve meşruiyet</strong> β†’ evrensel etik.</li>
+ </ul>
+ </div>
+ </div>
+
+ <p>2026 dünyasında neden acil? Üç neden:</p>
+ <ol>
+ <li><strong>İklim penceresi daralıyor.</strong> IPCC'ye gâre 2030'a kadar küresel karbon emisyonlarının %43 oranında azaltılması gerekir. Hızlı, derin ve yaygın dânüşüm şart.</li>
+ <li><strong>Teknolojik olgunluk eşiği aşıldı.</strong> Maliyet engeli artık birincil engel değil; kurumsal, davranışsal ve politik engeller birincil hale geldi.</li>
+ <li><strong>Toplumsal meşruiyet krizi.</strong> Fosil yakıt endüstrilerinin etki alanı, dânüşümü yavaşlatıyor. Demokratik meşruiyet sorunu.</li>
+ </ol>
+
+ <div class="pullquote">
+ Üç ayağın eşzamanlı varlığı, hareketin gücünü retorik bir cesaretten değil, <strong>yapısal bir bütünlükten</strong> almasını sağlar.
+ </div>
+</section>
+
+<section id="politika">
+ <h2>6. 2026–2030 politika ΓΆnerileri</h2>
+ <p>Güneş Uygarlığı'nın üç ayaklı modeli, somut politika adımlarına nasıl dânüşür? Aşağıdaki âneriler, makalenin ampirik katkısıdır.</p>
+
+ <div class="policy-grid">
+ <div class="policy">
+ <span class="policy-num">6.1</span>
+ <div class="policy-title">Enerji kooperatifleri yasasΔ±</div>
+ <p class="policy-body">1 MW altı güneş enerjisi için basitleştirilmiş lisans. Kooperatiflere imar ve teşvik ayrıcalığı. Kooperatif gelirinin yerel topluluk projelerine yânlendirilmesi için teşvik.</p>
+ <span class="policy-tag">Etik + Mimari ayak</span>
+ </div>
+ <div class="policy">
+ <span class="policy-num">6.2</span>
+ <div class="policy-title">Güneşkent pilot programı</div>
+ <p class="policy-body">5–10 ΓΆlΓ§ekli pilot. Pasif + aktif gΓΌneş mimarisi. Net enerji pozitif hedef. KatΔ±lΔ±mcΔ± planlama. Üniversitelerle sΓΌrekli izleme ortaklığı.</p>
+ <span class="policy-tag">Mimari + Akademik ayak</span>
+ </div>
+ <div class="policy">
+ <span class="policy-num">6.3</span>
+ <div class="policy-title">Güneş Okuryazarlığı eğitimi</div>
+ <p class="policy-body">İlkâğretimden yetişkin eğitimine. Fizik, ekoloji, ekonomi, etik birlikte âğretilir. Müfredat dânüşümü.</p>
+ <span class="policy-tag">Akademik + Etik ayak</span>
+ </div>
+ <div class="policy">
+ <span class="policy-num">6.4</span>
+ <div class="policy-title">Gelecek kuşak temsilciliği</div>
+ <p class="policy-body">Yerel meclislerde çocuk ve genç çıkarlarını temsil eden kurumsal mekanizma. Bağlayıcı danışma statüsü. Uluslararası ârnekler: Galler, Macaristan, Yeni Zelanda.</p>
+ <span class="policy-tag">Etik ayak</span>
+ </div>
+ <div class="policy">
+ <span class="policy-num">6.5</span>
+ <div class="policy-title">Güneş Diplomasisi</div>
+ <p class="policy-body">Akdeniz, Orta Doğu, Balkan ülkeleriyle güneş enerjisi paylaşım anlaşmaları. Türkiye'nin yeşil hidrojen merkezi olma potansiyeli. CBAM karşısında stratejik pozisyon.</p>
+ <span class="policy-tag">Akademik + Etik ayak</span>
+ </div>
+ <div class="policy">
+ <span class="policy-num">6.6</span>
+ <div class="policy-title">Açık veri ve şeffaflık</div>
+ <p class="policy-body">Tüm güneş enerjisi projelerinin üretim, emisyon, finansal verileri kamuya açık. Yeşil aklamayı ânler, bağımsız araştırmacı katkısını mümkün kılar.</p>
+ <span class="policy-tag">Akademik ayak</span>
+ </div>
+ </div>
+</section>
+
+<section id="tartisma">
+ <h2>7. AΓ§Δ±k sorular</h2>
+ <p>Bu makale, hareketin birikimine saygıyla yaklaşırken, açık soruları da işaretlemeyi gârev bilir.</p>
+
+ <h3>7.1 Γ–lΓ§ek sorunu</h3>
+ <p>Güneşkent modeli, tek bir kent veya mahalle âlçeğinde kanıtlanmış kavramlara dayanır. <strong>Metropol âlçeğinde</strong> (İstanbul, Ankara, İzmir) nasıl uygulanır? Hareketin, âlçekler arası geçiş stratejileri konusunda daha açık olması gerekir.</p>
+
+ <h3>7.2 Geçiş adaleti</h3>
+ <p>Fosil yakıtlara bağımlı ekonomilerin (kâmür bâlgeleri) güneş ekonomisine geçişi, iş kaybı, gelir kaybı ve kültürel kopuş riskleri taşır. Hareketin bu topluluklara âzgü bir geçiş programı ânermesi gerekir.</p>
+
+ <h3>7.3 Teknolojik çeşitlilik</h3>
+ <p>GΓΌneş enerjisi, düşük-karbon dΓΆnüşümΓΌn tek aracΔ± değildir. RΓΌzgΓ’r, jeotermal, düşük etkili hidroelektrik, nΓΌkleer (tartışmalΔ±), yeşil hidrojen β€” her birinin rolΓΌ bağlama gΓΆre değerlendirilmelidir.</p>
+
+ <h3>7.4 Kültürel çoğulculuk</h3>
+ <p>TΓΌrkiye, Γ§ok-kΓΌltΓΌrlΓΌ bir toplumdur; KΓΌrt, Arap, Γ‡erkez, Laz ve diğer gelenekler de Β«gΓΌneş» kavramΔ±nΔ± farklΔ± biΓ§imlerde taşır. Hareketin bu Γ§oğulculuğu ne ΓΆlΓ§ΓΌde kucakladığı aΓ§Δ±k olmalΔ±dΔ±r.</p>
+
+ <h3>7.5 Uluslararası karşılaştırmalı araştırma</h3>
+ <p>Üç ayaklı model, kapsamlı bir karşılaştırmalı uluslararası araştırma ile sınanmalıdır: hangi koşullar altında model âlçeklenebilir? Hangi kültürel bağlamlarda uyarlanması gerekir?</p>
+</section>
+
+<section id="sonuc">
+ <h2>8. Sonuç: Ütopya değil, program</h2>
+ <p>Güneş Uygarlığı hareketi, ütopya değil, program olduğunu açıkça ilan eder. Bu iddia, makalenin sınanması gereken çekirdek savunusunu oluşturur. Ütopya, ulaşılamayan idealdir; program, somut adımlar, âlçülebilir hedefler ve kurumsal mekanizmalar bütünüdür.</p>
+
+ <p>Bu makalenin sΔ±nanmasΔ± ΓΆnerilen tezi şudur: GΓΌneş Uygarlığı'nΔ±n <strong>ΓΌΓ§ ayaklΔ± modeli</strong> β€” 40 yΔ±llΔ±k akademik birikim, somut mimari projeler ve evrensel etik anlayış β€” düşük-karbon dΓΆnüşümΓΌn teknik, toplumsal ve etik boyutlarΔ±nΔ± birlikte ele alarak, parΓ§alΔ± reformlardan daha bΓΌtΓΌnlΓΌklΓΌ bir yol sunmaktadΔ±r.</p>
+
+ <blockquote class="pullquote">
+ Hareketin gücü, retorik bir cesaretten değil, <strong>üç ayağın eşzamanlı varlığından</strong> gelir.
+ </blockquote>
+
+ <p>Bu model, salt bir Türkiye meselesi değildir; iklim krizinin küresel âlçekte, bütüncül uygarlık dânüşümü gerektirdiği bir dânemde, ârnekleyici bir vaka olarak uluslararası literatüre de katkı sağlayabilir. Hareket, retorik bir cesaretten değil, üç ayağın eşzamanlı varlığından güç alır. Akademik birikim bilgi tabanını sağlar; somut projeler bilgiyi yeryüzüne indirir; evrensel etik her ikisine yân ve meşruiyet verir.</p>
+
+ <p>2026 yılında, bu modelin sınanması için yeterli teknolojik olgunluk, yeterli iklim aciliyeti ve yeterli toplumsal farkındalık mevcuttur. Soru, bu fırsatın değerlendirilip değerlendirilmeyeceğidir. Güneş Uygarlığı, bu soruya olumlu bir yanıt olarak konumlanmaktadır. Makale, bu yanıtın hem takdir edilmesini hem de akademik titizlikle sınanmasını savunur.</p>
+</section>
+
+<section>
+ <h2>KaynakΓ§a</h2>
+ <div class="refs">
+ <h4>Hareketin kendi kaynaklarΔ±</h4>
+ <ul>
+ <li><a href="https://webx11.duckdns.org/spaces/gunesuygarligi/manifesto.html">Güneş Uygarlığı Manifestosu</a> (Anadolu Aydınlık Derneği / Aydınlık Belediyesi yayını).</li>
+ <li><a href="https://webx11.duckdns.org/spaces/gunesuygarligi/solarcity.html">Güneşkent projeleri</a> ve belediye yayınları.</li>
+ <li><a href="https://webx11.duckdns.org/spaces/gunesuygarligi/call.html">Β«GΓΌneşe Γ‡ağrΔ±Β»</a> β€” hareketin temel metni.</li>
+ </ul>
+ <h4>Akademik ve politika kaynaklarΔ±</h4>
+ <ul>
+ <li>IRENA (2024). <em>World Energy Transitions Outlook</em>. Abu Dhabi.</li>
+ <li>IPCC (2023). <em>AR6 Synthesis Report: Climate Change 2023</em>. Geneva.</li>
+ <li>Jackson, T. (2017). <em>Prosperity Without Growth</em> (2nd ed.). Routledge.</li>
+ <li>Odum, H. T. (2007). <em>Environment, Power, and Society for the Twenty-First Century</em>. Columbia University Press.</li>
+ <li>Geels, F. W. (2002). Β«Technological transitions as evolutionary reconfiguration processes.Β» <em>Research Policy</em>, 31(8–9).</li>
+ <li>Seyfang, G. (2010). Β«Community action for sustainable housing.Β» <em>Global Environmental Change</em>, 20(2).</li>
+ <li>Devine-Wright, P. (2009). Β«Rethinking NIMBYism.Β» <em>Global Environmental Change</em>, 19(2).</li>
+ </ul>
+ <h4>Türkiye bağlamında</h4>
+ <ul>
+ <li>T.C. Enerji ve Tabii Kaynaklar Bakanlığı, <em>Türkiye Güneş Enerjisi Potansiyeli Atlası</em> (GEPA).</li>
+ <li>TÜİK, <em>Hanehalkı Enerji Tüketim Araştırması</em>.</li>
+ <li>UNDP TΓΌrkiye, <em>SΓΌrdΓΌrΓΌlebilir Enerji RaporlarΔ±</em>.</li>
+ </ul>
+ <h4>Genel ekoloji ve uygarlΔ±k kuramlarΔ±</h4>
+ <ul>
+ <li>Mumford, L. (1967). <em>The Myth of the Machine: Technics and Human Development</em>. Harcourt Brace.</li>
+ <li>Bookchin, M. (1990). <em>The Philosophy of Social Ecology</em>. Black Rose Books.</li>
+ <li>Latour, B. (2017). <em>Facing Gaia: Eight Lectures on the New Climatic Regime</em>. Polity.</li>
+ </ul>
+ </div>
+</section>
+
+<footer>
+ <p><span class="accent">Yazara not.</span> Bu makale, yapay zekÒ destekli bir taslak olarak üretilmiştir. Yapay zekÒ yapıyı, literatür taramasını ve dil düzeltmesini sağlamış; <strong>somut veriler, alıntılar ve yorumsal çerçeve</strong> için nihai sorumluluk yazara aittir.</p>
+ <p>Akademik yayın sürecine taşınması durumunda, hakemli dergi formatına uyarlanması, kaynakların birincil metinlerle doğrulanması ve YZ katkısının açıkça beyan edilmesi ânerilir.</p>
+ <p style="margin-top: 16px;">Taslak tamamlandΔ±: 6 Temmuz 2026, 03:58 (UTC+3)</p>
+ <p>Kaynak platform: <a href="https://webx11.duckdns.org/spaces/gunesuygarligi/" target="_blank" rel="noopener">webx11.duckdns.org/spaces/gunesuygarligi</a></p>
+</footer>
+
+</main>
+
+<button class="top-btn" id="topBtn" aria-label="YukarΔ± dΓΆn">↑</button>
+
+<script>
+ const progress = document.getElementById('progress');
+ const topBtn = document.getElementById('topBtn');
+ function update() {
+ const h = document.documentElement;
+ const scrolled = (h.scrollTop) / (h.scrollHeight - h.clientHeight) * 100;
+ progress.style.width = Math.min(scrolled, 100) + '%';
+ if (h.scrollTop > 600) topBtn.classList.add('visible');
+ else topBtn.classList.remove('visible');
+ }
+ window.addEventListener('scroll', update, { passive: true });
+ topBtn.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' }));
+</script>
+
+</body>
+</html>
diff --git a/downloads/kb.html b/downloads/kb.html
new file mode 100644
index 0000000..0159403
--- /dev/null
+++ b/downloads/kb.html
@@ -0,0 +1,481 @@
+```html
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>newOS4 v4.5.83 β€” System Architecture Audit & Improvement Blueprint</title>
+<style>
+ * { margin: 0; padding: 0; box-sizing: border-box; }
+ body {
+ background: #0a0a12;
+ color: #c8d0e0;
+ font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
+ line-height: 1.6;
+ padding: 2rem 1.5rem;
+ max-width: 1200px;
+ margin: 0 auto;
+ }
+ h1 { font-size: 2.2rem; color: #7ec8e3; border-bottom: 2px solid #1e3a5f; padding-bottom: 0.5rem; margin-bottom: 1.5rem; }
+ h2 { font-size: 1.5rem; color: #9ad0f5; margin: 2rem 0 0.8rem; border-left: 4px solid #2a6f97; padding-left: 0.8rem; }
+ h3 { font-size: 1.15rem; color: #b8d8f0; margin: 1.2rem 0 0.5rem; }
+ .meta { color: #8899aa; font-size: 0.9rem; margin-bottom: 2rem; }
+ .meta span { background: #14141e; padding: 0.2rem 0.6rem; border-radius: 4px; margin-right: 0.5rem; }
+ .summary-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
+ gap: 0.8rem;
+ margin: 1.5rem 0;
+ }
+ .stat-card {
+ background: #11111a;
+ border: 1px solid #1e2a3a;
+ border-radius: 8px;
+ padding: 0.8rem 1rem;
+ text-align: center;
+ }
+ .stat-card .num { font-size: 1.8rem; font-weight: 700; color: #7ec8e3; }
+ .stat-card .label { font-size: 0.75rem; color: #6a7a8a; text-transform: uppercase; letter-spacing: 0.5px; }
+ .stat-card.warn .num { color: #f0b37e; }
+ .stat-card.bad .num { color: #e07070; }
+ .stat-card.good .num { color: #7ec8e3; }
+
+ .severity { display: inline-block; padding: 0.15rem 0.5rem; border-radius: 4px; font-size: 0.7rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px; }
+ .sev-p1 { background: #3a1515; color: #e07070; border: 1px solid #5a2020; }
+ .sev-p2 { background: #2a2a10; color: #e0c070; border: 1px solid #4a4a15; }
+ .sev-p3 { background: #15202a; color: #70a0c0; border: 1px solid #1a3040; }
+ .sev-ok { background: #0a1a0a; color: #70c070; border: 1px solid #1a3a1a; }
+
+ table { width: 100%; border-collapse: collapse; margin: 1rem 0; font-size: 0.9rem; }
+ th { background: #0e0e18; color: #7ec8e3; padding: 0.5rem 0.8rem; text-align: left; border-bottom: 2px solid #1e3a5f; font-weight: 600; }
+ td { padding: 0.5rem 0.8rem; border-bottom: 1px solid #181828; }
+ tr:hover td { background: #0e0e1a; }
+
+ .issue { background: #0c0c16; border: 1px solid #1a1a2a; border-radius: 8px; padding: 1rem; margin: 0.8rem 0; }
+ .issue h4 { color: #c8d0e0; margin-bottom: 0.3rem; }
+ .issue .desc { color: #8899aa; font-size: 0.9rem; margin: 0.3rem 0; }
+ .issue .impact { color: #a0b0c0; font-size: 0.85rem; margin-top: 0.3rem; padding-left: 0.5rem; border-left: 2px solid #2a3a4a; }
+
+ .rec-card {
+ background: #0e0e1a;
+ border: 1px solid #1a2a3a;
+ border-radius: 8px;
+ padding: 1rem;
+ margin: 0.6rem 0;
+ display: flex;
+ gap: 1rem;
+ align-items: flex-start;
+ }
+ .rec-card .tag { flex-shrink: 0; }
+ .rec-card .body { flex: 1; }
+ .rec-card .body h4 { color: #9ad0f5; margin-bottom: 0.2rem; }
+ .rec-card .body p { color: #8899aa; font-size: 0.85rem; }
+ .effort { display: inline-block; padding: 0.1rem 0.4rem; border-radius: 3px; font-size: 0.7rem; background: #1a1a2a; color: #7a8a9a; }
+
+ .arch-diagram {
+ background: #0c0c16;
+ border: 1px solid #1a2a3a;
+ border-radius: 8px;
+ padding: 1.2rem;
+ margin: 1rem 0;
+ font-family: 'Courier New', monospace;
+ font-size: 0.8rem;
+ line-height: 1.5;
+ color: #7a9ab0;
+ white-space: pre;
+ overflow-x: auto;
+ }
+
+ .section-toggle { cursor: pointer; user-select: none; }
+ .section-toggle:hover { color: #7ec8e3; }
+
+ .footer { margin-top: 3rem; padding-top: 1rem; border-top: 1px solid #1a1a2a; color: #5a6a7a; font-size: 0.8rem; text-align: center; }
+</style>
+</head>
+<body>
+
+<h1>πŸ” newOS4 v4.5.83 β€” System Architecture Audit</h1>
+<div class="meta">
+ <span>πŸ“… 2026-07-03 16:14 UTC</span>
+ <span>🧠 Role: Architect</span>
+ <span>πŸ”§ 43 modules Β· 37 skills Β· 38 files</span>
+ <span>πŸ’Ύ 23.4 MB memory Β· βœ… Ollama connected</span>
+</div>
+
+<div class="summary-grid">
+ <div class="stat-card good"><div class="num">43</div><div class="label">Modules Loaded</div></div>
+ <div class="stat-card good"><div class="num">37</div><div class="label">Skills Active</div></div>
+ <div class="stat-card warn"><div class="num">27</div><div class="label">Memory Graph Nodes</div></div>
+ <div class="stat-card warn"><div class="num">30</div><div class="label">Memory Graph Edges</div></div>
+ <div class="stat-card bad"><div class="num">0</div><div class="label">Active Agents</div></div>
+ <div class="stat-card bad"><div class="num">10</div><div class="label">Stale Leases</div></div>
+ <div class="stat-card bad"><div class="num">12</div><div class="label">Empty Directories</div></div>
+ <div class="stat-card bad"><div class="num">4</div><div class="label">Stale Version Files</div></div>
+</div>
+
+<!-- ============================================================ -->
+<h2>1. πŸ—οΈ System Architecture Overview</h2>
+
+<div class="arch-diagram">
+β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
+β”‚ newOS4 v4.5.83 β€” Layer Map β”‚
+β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
+β”‚ β”‚
+β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
+β”‚ β”‚ 🧠 AI LAYER β”‚ β”‚
+β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
+β”‚ β”‚ β”‚ Ollama β”‚ β”‚ SmartCtx β”‚ β”‚ Memory β”‚ β”‚ World β”‚ β”‚ β”‚
+β”‚ β”‚ β”‚ Module β”‚ β”‚ Module β”‚ β”‚ Graph β”‚ β”‚ Model β”‚ β”‚ β”‚
+β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
+β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
+β”‚ β”‚ β”‚ Predictorβ”‚ β”‚ Agent β”‚ β”‚ Leases β”‚ β”‚Orchestr. β”‚ β”‚ β”‚
+β”‚ β”‚ β”‚ Module β”‚ β”‚ Registry β”‚ β”‚ Module β”‚ β”‚ Module β”‚ β”‚ β”‚
+β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
+β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
+β”‚ β”‚ β”‚
+β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
+β”‚ β”‚ πŸ”§ MODULE LAYER (43 modules) β”‚ β”‚
+β”‚ β”‚ Core (21): System, FS, ModMgr, Config, Ollama, β”‚ β”‚
+β”‚ β”‚ SearXNG, Fetcher, AI Assist, AI Alias, SecretVault, β”‚ β”‚
+β”‚ β”‚ ChatStudio, AgentReg, Leases, Orchestrator, NeuralVFS, β”‚ β”‚
+β”‚ β”‚ Sandbox, MemoryGraph, Predictor, WorldModel, β”‚ β”‚
+β”‚ β”‚ ServerMonitor, SmartContext β”‚ β”‚
+β”‚ β”‚ Ext (22): Editor, Shell, Alias, Finder, FileMgr, Diff, β”‚ β”‚
+β”‚ β”‚ BusyBox, Calc, Voice, Debug, Cron, Theme, WPM, Mindmap,β”‚ β”‚
+β”‚ β”‚ WebDAV, SkillPack, CryptoGzip, Tutorial, Floating, β”‚ β”‚
+β”‚ β”‚ JSConsole, Media, Three β”‚ β”‚
+β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
+β”‚ β”‚ β”‚
+β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
+β”‚ β”‚ πŸ“ VFS LAYER (Virtual File System) β”‚ β”‚
+β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
+β”‚ β”‚ β”‚ Gzip β”‚ β”‚IndexedDB β”‚ β”‚ Checkpt β”‚ β”‚ Neural β”‚ β”‚ β”‚
+β”‚ β”‚ β”‚ Compress β”‚ β”‚ Fallback β”‚ β”‚ Rollback β”‚ β”‚ VFS β”‚ β”‚ β”‚
+β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
+β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚
+β”‚ β”‚ β”‚ Trash β”‚ β”‚ Virtual β”‚ β”‚ Session β”‚ β”‚ β”‚
+β”‚ β”‚ β”‚ System β”‚ β”‚ /sys/ β”‚ β”‚ Manager β”‚ β”‚ β”‚
+β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
+β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
+β”‚ β”‚
+β”‚ ⚠️ CRITICAL: No beforeunload flush β€” data loss on page close β”‚
+β”‚ ⚠️ sys/ directory leak in every VFS directory β”‚
+β”‚ ⚠️ Duplicate module-modmgr vs module-manager commands β”‚
+β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
+</div>
+
+<!-- ============================================================ -->
+<h2>2. 🚨 Critical Issues (P1 β€” Must Fix)</h2>
+
+<div class="issue">
+ <h4><span class="severity sev-p1">P1</span> πŸ”΄ Data Loss: No `beforeunload` Flush</h4>
+ <div class="desc"><strong>Location:</strong> VirtualFileSystem.saveToStorage() β€” debounce timer</div>
+ <div class="desc">The VFS uses a 2-second <code>setTimeout</code> debounce before writing to localStorage. If the user closes the tab or navigates away within that window, <strong>the write is silently lost</strong>. There is no <code>window.addEventListener('beforeunload', ...)</code> handler to force-flush pending saves.</div>
+ <div class="impact">πŸ’₯ <strong>Impact:</strong> Silent, unrecoverable data loss on page close. Every unsaved file edit, config change, or session state is at risk.</div>
+ <div class="impact">πŸ”§ <strong>Fix:</strong> Add <code>window.addEventListener('beforeunload', flushPendingSave)</code> that synchronously writes pending data. Also add a visual "Saving..." indicator.</div>
+</div>
+
+<div class="issue">
+ <h4><span class="severity sev-p1">P1</span> πŸ”΄ `rmdir` Command Silently Trashes Non-Empty Directories</h4>
+ <div class="desc"><strong>Location:</strong> FileSystemModule β€” <code>rmdir</code> command handler</div>
+ <div class="desc">The <code>rmdir</code> command calls <code>fs.deleteDirRecursive()</code> β†’ <code>trashDir()</code>, which <strong>trashes the entire directory tree</strong> without checking if the directory is empty. Unix <code>rmdir</code> requires empty directories. The underlying <code>VirtualFileSystem.rmdir()</code> method <em>does</em> check emptiness, but the command bypasses it.</div>
+ <div class="impact">πŸ’₯ <strong>Impact:</strong> User expects <code>rmdir</code> to be safe (fails if not empty), but it silently nukes entire directory trees. Accidental data loss.</div>
+ <div class="impact">πŸ”§ <strong>Fix:</strong> Change <code>rmdir</code> command to call <code>fs.rmdir()</code> (which checks emptiness) instead of <code>deleteDirRecursive</code>. Add a separate <code>rm -rf</code> or <code>trash</code> command for recursive deletion.</div>
+</div>
+
+<!-- ============================================================ -->
+<h2>3. ⚠️ Structural Issues (P2 β€” Should Fix)</h2>
+
+<h3>3.1 🧩 The `sys/` Directory Leak</h3>
+<p style="color:#8899aa; margin-bottom:0.5rem;">Every single VFS directory contains a <code>sys/</code> subdirectory β€” 22 occurrences found. This is a virtual mount artifact leaking into persistent storage.</p>
+<table>
+ <tr><th>Affected Directories</th><th>Count</th></tr>
+ <tr><td>/, /config, /system, /memory, /logs, /projects, /agents, /_agents, /skills, /scripts, /docs, /_docs, /_security, /_contexts, /leases, /mindmaps, /exports, /tmp, /archive, /_sessions, /.memory_graph, /.semantic_index</td><td><strong>22</strong></td></tr>
+</table>
+<div class="issue">
+ <div class="desc"><strong>Root Cause:</strong> The virtual <code>/sys/</code> mount system is creating real directory nodes in the VFS tree during path resolution or directory listing. This causes:</div>
+ <div class="impact">πŸ“ˆ Directory bloat β€” every dir gets a useless <code>sys</code> child</div>
+ <div class="impact">πŸ” Confusion in <code>tree</code> and <code>ls -R</code> output</div>
+ <div class="impact">πŸ’Ύ Unnecessary persistence to localStorage</div>
+ <div class="impact">πŸ”§ <strong>Fix:</strong> Audit the virtual mount resolver. Ensure <code>/sys/</code> paths are intercepted before VFS node creation, or add a filter in <code>listDirectory()</code> to exclude virtual mount artifacts.</div>
+</div>
+
+<h3>3.2 🧩 Duplicate Module: module-modmgr vs module-manager</h3>
+<table>
+ <tr><th>Module</th><th>Class</th><th>Status</th><th>Commands</th></tr>
+ <tr><td>module-manager</td><td>ModuleManager</td><td>βœ… Active, auto_load: true</td><td>modules, listmods, loadmod, removemod, startup-modules, load-local, loadlocal</td></tr>
+ <tr><td>module-modmgr</td><td>ModuleManagerModule</td><td>⚠️ DEPRECATED 2026-06-08, auto_load: false</td><td>modules, listmods, loadmod, removemod, startup-modules, load-local, loadlocal</td></tr>
+</table>
+<div class="issue">
+ <div class="desc"><strong>Problem:</strong> Both modules register identical commands. At runtime, it's unclear which handler actually executes. The deprecated module is still loaded and its class is registered.</div>
+ <div class="impact">πŸ”§ <strong>Fix:</strong> Remove <code>module-modmgr</code> from the module index entirely. Unregister its command handlers. Ensure <code>module-manager</code> is the sole owner of these commands.</div>
+</div>
+
+<h3>3.3 🧩 Stale Artifacts & Orphaned Data</h3>
+<table>
+ <tr><th>Artifact</th><th>Location</th><th>Issue</th></tr>
+ <tr><td><code>manifest.json</code></td><td>/</td><td>References 4 agents (pulse-check, project-summarizer, the-oracle, bridge-worker) that <strong>do not exist</strong> in the current system. Orphaned metadata.</td></tr>
+ <tr><td><code>baseline_v1.json</code></td><td>/</td><td>Timestamp 2024-05-22 β€” over 2 years old. References old models (kimi-k2.7-code, gemma4:31b).</td></tr>
+ <tr><td><code>v4.5.80</code>, <code>v4.5.80debug</code>, <code>v4.5.81</code>, <code>v4.5.82</code></td><td>/</td><td>Changelog notes dumped in root directory. Should be in <code>/docs/</code> or <code>/archive/</code>.</td></tr>
+ <tr><td><code>debug.log</code></td><td>/</td><td>Only 2 entries from Jun 25. Not rotated, not useful.</td></tr>
+ <tr><td><code>archive/legacy_artifacts</code></td><td>/archive/</td><td>Contains an AI tool-use optimization report β€” not a filesystem archive. Content doesn't match location.</td></tr>
+ <tr><td><code>scripts/vfs_utils.js</code></td><td>/scripts/</td><td>Uses <code>require('fs')</code> β€” Node.js dead code, can't run in browser.</td></tr>
+ <tr><td><code>scripts/health_audit.js</code></td><td>/scripts/</td><td>Stub β€” logs "Audit started..." then does nothing.</td></tr>
+ <tr><td><code>startup.sh</code></td><td>/</td><td>Contains terminal commands (<code>setfont 16</code>, <code>theme set monochrome</code>), not a shell script. Misleading filename.</td></tr>
+ <tr><td><code>loop-lesson-*</code> (7 files)</td><td>/skills/</td><td>Auto-generated loop lessons that should be pruned or archived.</td></tr>
+</table>
+
+<h3>3.4 🧩 Empty / Phantom Directories</h3>
+<table>
+ <tr><th>Directory</th><th>Contents</th><th>Notes</th></tr>
+ <tr><td>/docs/</td><td>sys/ (empty)</td><td>Dead β€” no documentation files</td></tr>
+ <tr><td>/_docs/</td><td>sys/ (empty)</td><td>Dead β€” duplicate of /docs/</td></tr>
+ <tr><td>/_security/</td><td>sys/ (empty)</td><td>Dead β€” no security configs</td></tr>
+ <tr><td>/_contexts/</td><td>sys/ (empty)</td><td>Dead β€” no context files</td></tr>
+ <tr><td>/agents/</td><td>register/ + 12 agent dirs + sys/</td><td>Has content but also duplicate of /_agents/</td></tr>
+ <tr><td>/_agents/</td><td>sys/ (empty)</td><td>Duplicate of /agents/ β€” remove one</td></tr>
+ <tr><td>/projects/</td><td>nebula/, automations/, sys/</td><td>Has subdirs but no project data</td></tr>
+ <tr><td>/mindmaps/</td><td>sys/ (empty)</td><td>Dead β€” no saved mindmaps</td></tr>
+ <tr><td>/leases/</td><td>10 stale leases + sys/</td><td>Stale leases should be purged</td></tr>
+</table>
+
+<h3>3.5 🧩 Stale Agent Leases</h3>
+<p style="color:#8899aa; margin-bottom:0.5rem;">10 lease files found in <code>/leases/</code> β€” all appear to be from completed or abandoned agent tasks. No active agents exist (0 active, 0 busy).</p>
+<table>
+ <tr><th>Lease File</th><th>Timestamp</th></tr>
+ <tr><td>lease-1782051934228.json</td><td>~Jun 20</td></tr>
+ <tr><td>lease-1782051934258.json</td><td>~Jun 20</td></tr>
+ <tr><td>lease-1782051944362.json</td><td>~Jun 20</td></tr>
+ <tr><td>lease-1782052010895.json</td><td>~Jun 20</td></tr>
+ <tr><td>lease-1782116963490.json</td><td>~Jun 21</td></tr>
+ <tr><td>lease-1782214294550.json</td><td>~Jun 22</td></tr>
+ <tr><td>lease-1782235322842.json</td><td>~Jun 22</td></tr>
+ <tr><td>lease-1782235340660.json</td><td>~Jun 22</td></tr>
+ <tr><td>lease-1782235355578.json</td><td>~Jun 22</td></tr>
+ <tr><td>lease-1782347129356.json</td><td>~Jun 24</td></tr>
+</table>
+
+<!-- ============================================================ -->
+<h2>4. πŸ”§ Minor Issues (P3 β€” Nice to Fix)</h2>
+
+<table>
+ <tr><th>#</th><th>Issue</th><th>Details</th></tr>
+ <tr><td>1</td><td><code>find</code> double-lowercases pattern</td><td>Command does <code>args[0].toLowerCase()</code> before passing to <code>fs.findFiles()</code> which already uses case-insensitive regex. Uppercase regex patterns break.</td></tr>
+ <tr><td>2</td><td>Trash flattens directory structure</td><td>When trashing a directory, files are flattened into trash root with timestamp prefixes. Directory tree structure is lost.</td></tr>
+ <tr><td>3</td><td>Session v1 restore is destructive</td><td>Loading a v1 session replaces entire <code>fs.root</code> with no warning.</td></tr>
+ <tr><td>4</td><td>No save indication</td><td><code>saveToStorage()</code> is silent β€” no visual feedback when VFS is saved.</td></tr>
+ <tr><td>5</td><td><code>du</code> command is incomplete</td><td>Only handles current dir or single file. No recursive directory size display.</td></tr>
+ <tr><td>6</td><td><code>grep</code> without filename only searches current dir</td><td>Not recursive. Unix <code>grep</code> would search stdin or use <code>-r</code>.</td></tr>
+ <tr><td>7</td><td>Memory Graph: 27 nodes, 30 edges</td><td>Low connectivity ratio (1.1 edges/node). Sparse graph limits cross-session inference.</td></tr>
+ <tr><td>8</td><td>0 active agents despite 12 agent dirs</td><td>Agent registry has 12 registered agent directories but 0 active. Agents may be orphaned.</td></tr>
+</table>
+
+<!-- ============================================================ -->
+<h2>5. βœ… What's Working Well</h2>
+
+<table>
+ <tr><th>Component</th><th>Status</th><th>Notes</th></tr>
+ <tr><td>Gzip compression</td><td><span class="severity sev-ok">βœ…</span></td><td>CompressionStream + base64, 2x smaller than legacy format</td></tr>
+ <tr><td>IndexedDB fallback</td><td><span class="severity sev-ok">βœ…</span></td><td>Auto-falls back when localStorage quota exceeded</td></tr>
+ <tr><td>Legacy migration</td><td><span class="severity sev-ok">βœ…</span></td><td>Old uncompressed format auto-migrates to v2 compressed</td></tr>
+ <tr><td>Trash system</td><td><span class="severity sev-ok">βœ…</span></td><td>Auto-purge after 24h, <code>ls-trash</code>, <code>empty-trash</code> commands</td></tr>
+ <tr><td>Checkpoint/rollback</td><td><span class="severity sev-ok">βœ…</span></td><td>Auto-manages max 3, strips system dirs from snapshots</td></tr>
+ <tr><td>Virtual /sys/</td><td><span class="severity sev-ok">βœ…</span></td><td>Live runtime state without persistence β€” elegant design</td></tr>
+ <tr><td>NeuralVFS integration</td><td><span class="severity sev-ok">βœ…</span></td><td>Decoupled via window events, zero coupling</td></tr>
+ <tr><td>Session v2 format</td><td><span class="severity sev-ok">βœ…</span></td><td>Metadata-only, VFS persists independently</td></tr>
+ <tr><td>Path resolution</td><td><span class="severity sev-ok">βœ…</span></td><td>Handles <code>.</code>, <code>..</code>, absolute, relative, virtual paths</td></tr>
+ <tr><td>Module ecosystem</td><td><span class="severity sev-ok">βœ…</span></td><td>43 modules, all loaded, 0 errors, 0 local edits</td></tr>
+ <tr><td>Ollama connectivity</td><td><span class="severity sev-ok">βœ…</span></td><td>Connected to deepseek-v4-flash:cloud</td></tr>
+ <tr><td>Memory Graph</td><td><span class="severity sev-ok">βœ…</span></td><td>27 nodes, 30 edges, active, no fallback</td></tr>
+ <tr><td>World Model</td><td><span class="severity sev-ok">βœ…</span></td><td>v4.5.83 synthesized, health OK</td></tr>
+ <tr><td>Skills system</td><td><span class="severity sev-ok">βœ…</span></td><td>37 skills, well-organized, index maintained</td></tr>
+ <tr><td>WebDAV backup</td><td><span class="severity sev-ok">βœ…</span></td><td>Cloud backup/restore functional</td></tr>
+ <tr><td>Sandbox module</td><td><span class="severity sev-ok">βœ…</span></td><td>WebWorker pool for isolated execution</td></tr>
+ <tr><td>Predictor module</td><td><span class="severity sev-ok">βœ…</span></td><td>Task duration estimation from history</td></tr>
+ <tr><td>SmartContext</td><td><span class="severity sev-ok">βœ…</span></td><td>AI context profiles for different modes</td></tr>
+</table>
+
+<!-- ============================================================ -->
+<h2>6. πŸ“‹ Recommended Action Plan</h2>
+
+<div class="rec-card">
+ <div class="tag"><span class="severity sev-p1">P1</span></div>
+ <div class="body">
+ <h4>Add beforeunload flush handler</h4>
+ <p>Prevent silent data loss on page close. Add <code>window.addEventListener('beforeunload', flushPendingSave)</code> to VirtualFileSystem. Also add a visual "Saving..." indicator.</p>
+ <span class="effort">⏱️ Effort: Low (30 min)</span>
+ </div>
+</div>
+
+<div class="rec-card">
+ <div class="tag"><span class="severity sev-p1">P1</span></div>
+ <div class="body">
+ <h4>Fix rmdir command to check emptiness</h4>
+ <p>Change <code>rmdir</code> to use <code>fs.rmdir()</code> (which checks emptiness) instead of <code>deleteDirRecursive</code>. Add <code>rm -rf</code> or <code>trash</code> for recursive deletion.</p>
+ <span class="effort">⏱️ Effort: Low (15 min)</span>
+ </div>
+</div>
+
+<div class="rec-card">
+ <div class="tag"><span class="severity sev-p2">P2</span></div>
+ <div class="body">
+ <h4>Fix sys/ directory leak</h4>
+ <p>Audit virtual mount resolver. Ensure <code>/sys/</code> paths are intercepted before VFS node creation. Add filter in <code>listDirectory()</code> to exclude virtual mount artifacts.</p>
+ <span class="effort">⏱️ Effort: Medium (1-2 hrs)</span>
+ </div>
+</div>
+
+<div class="rec-card">
+ <div class="tag"><span class="severity sev-p2">P2</span></div>
+ <div class="body">
+ <h4>Remove duplicate module-modmgr</h4>
+ <p>Remove <code>module-modmgr</code> from module index. Unregister its command handlers. Ensure <code>module-manager</code> is the sole owner.</p>
+ <span class="effort">⏱️ Effort: Low (20 min)</span>
+ </div>
+</div>
+
+<div class="rec-card">
+ <div class="tag"><span class="severity sev-p2">P2</span></div>
+ <div class="body">
+ <h4>Spring cleaning: prune stale artifacts</h4>
+ <p>Move version files to <code>/archive/</code>. Update or remove <code>manifest.json</code> and <code>baseline_v1.json</code>. Remove dead scripts. Clean up <code>loop-lesson-*</code> skills. Purge stale leases.</p>
+ <span class="effort">⏱️ Effort: Medium (1 hr)</span>
+ </div>
+</div>
+
+<div class="rec-card">
+ <div class="tag"><span class="severity sev-p2">P2</span></div>
+ <div class="body">
+ <h4>Consolidate duplicate directories</h4>
+ <p>Remove <code>/_agents/</code> (duplicate of <code>/agents/</code>). Remove <code>/_docs/</code> (duplicate of <code>/docs/</code>). Remove empty dirs: <code>/_security/</code>, <code>/_contexts/</code>, <code>/_contracts/</code>.</p>
+ <span class="effort">⏱️ Effort: Low (15 min)</span>
+ </div>
+</div>
+
+<div class="rec-card">
+ <div class="tag"><span class="severity sev-p3">P3</span></div>
+ <div class="body">
+ <h4>Fix find double-lowercase bug</h4>
+ <p>Remove <code>.toLowerCase()</code> from <code>find</code> command handler β€” regex already handles case-insensitivity.</p>
+ <span class="effort">⏱️ Effort: Low (5 min)</span>
+ </div>
+</div>
+
+<div class="rec-card">
+ <div class="tag"><span class="severity sev-p3">P3</span></div>
+ <div class="body">
+ <h4>Improve trash to preserve directory structure</h4>
+ <p>Store trashed directories as nested structures instead of flat timestamp-prefixed files.</p>
+ <span class="effort">⏱️ Effort: Medium (1 hr)</span>
+ </div>
+</div>
+
+<div class="rec-card">
+ <div class="tag"><span class="severity sev-p3">P3</span></div>
+ <div class="body">
+ <h4>Add save confirmation indicator</h4>
+ <p>Show a brief "πŸ’Ύ Saved" toast or status indicator when VFS writes to storage.</p>
+ <span class="effort">⏱️ Effort: Low (15 min)</span>
+ </div>
+</div>
+
+<div class="rec-card">
+ <div class="tag"><span class="severity sev-p3">P3</span></div>
+ <div class="body">
+ <h4>Enrich Memory Graph connectivity</h4>
+ <p>Current ratio is 1.1 edges/node. Aim for 2-3 edges/node by adding cross-references between related files, skills, and concepts.</p>
+ <span class="effort">⏱️ Effort: Ongoing</span>
+ </div>
+</div>
+
+<!-- ============================================================ -->
+<h2>7. πŸ“Š Dependency Graph Analysis</h2>
+
+<div class="arch-diagram">
+Module Dependency Map (simplified):
+
+ SystemModule ──┬── FileSystemModule ──┬── NeuralVFSModule
+ β”‚ └── CryptoGzipModule
+ β”œβ”€β”€ ConfigManagerModule
+ β”œβ”€β”€ ModuleManagerModule β”€β”€βš οΈ DUPLICATE with module-manager
+ β”œβ”€β”€ OllamaModule ──┬── SmartContextModule
+ β”‚ └── WebX11AIAssistantModule
+ β”œβ”€β”€ SearXNGModule ── WebFetcherModule
+ β”œβ”€β”€ AgentRegistryModule ──┬── LeasesModule
+ β”‚ └── OrchestratorModule
+ β”œβ”€β”€ MemoryGraphModule ── WorldModelModule
+ β”œβ”€β”€ PredictorModule
+ β”œβ”€β”€ ServerMonitorModule
+ └── SandboxModule
+
+ Ext Modules (independent):
+ Editor, Shell, Alias, Finder, FileMgr, Diff, BusyBox,
+ Calc, Voice, Debug, Cron, Theme, WPM, Mindmap, WebDAV,
+ SkillPack, Tutorial, Floating, JSConsole, Media, Three
+
+ ⚠️ Critical Path: VFS β†’ localStorage (no beforeunload guard)
+ ⚠️ Duplicate: module-modmgr ↔ module-manager (command collision)
+ ⚠️ Orphaned: manifest.json references 4 agents that don't exist
+ ⚠️ Dead code: scripts/vfs_utils.js (Node.js require in browser)
+</div>
+
+<!-- ============================================================ -->
+<h2>8. 🧠 Strategic Recommendations</h2>
+
+<div class="issue" style="border-color: #1a3a2a;">
+ <h4>🎯 Short-term (this session)</h4>
+ <ul style="color:#8899aa; margin:0.5rem 0 0 1.2rem; font-size:0.9rem;">
+ <li>Add <code>beforeunload</code> flush β€” highest priority, prevents data loss</li>
+ <li>Fix <code>rmdir</code> command β€” prevents accidental data loss</li>
+ <li>Remove duplicate <code>module-modmgr</code> β€” cleans up command namespace</li>
+ <li>Prune stale leases and empty directories β€” reduces VFS clutter</li>
+ </ul>
+</div>
+
+<div class="issue" style="border-color: #1a2a3a;">
+ <h4>🎯 Medium-term (next 3 sessions)</h4>
+ <ul style="color:#8899aa; margin:0.5rem 0 0 1.2rem; font-size:0.9rem;">
+ <li>Fix <code>sys/</code> directory leak β€” structural integrity issue</li>
+ <li>Implement VFS save indicator β€” user experience improvement</li>
+ <li>Add recursive <code>du</code> and <code>grep -r</code> β€” feature parity with Unix</li>
+ <li>Enrich Memory Graph connectivity β€” better cross-session inference</li>
+ <li>Create proper documentation in <code>/docs/</code> β€” fill the empty directory</li>
+ </ul>
+</div>
+
+<div class="issue" style="border-color: #1a2a3a;">
+ <h4>🎯 Long-term (architectural)</h4>
+ <ul style="color:#8899aa; margin:0.5rem 0 0 1.2rem; font-size:0.9rem;">
+ <li>Implement VFS transaction log for crash recovery</li>
+ <li>Add VFS integrity checksum on every save</li>
+ <li>Create automated VFS health monitoring (replace stub <code>health_audit.js</code>)</li>
+ <li>Implement agent auto-revival from registry (12 registered, 0 active)</li>
+ <li>Build a proper project management system in <code>/projects/</code></li>
+ <li>Add automated lease cleanup (purge leases older than 7 days)</li>
+ <li>Consider migrating from localStorage to IndexedDB as primary storage</li>
+ </ul>
+</div>
+
+<!-- ============================================================ -->
+<h2>9. πŸ“ˆ System Health Score</h2>
+
+<div class="summary-grid">
+ <div class="stat-card good"><div class="num">85%</div><div class="label">Module Health</div></div>
+ <div class="stat-card warn"><div class="num">65%</div><div class="label">VFS Integrity</div></div>
+ <div class="stat-card warn"><div class="num">70%</div><div class="label">Data Safety</div></div>
+ <div class="stat-card bad"><div class="num">40%</div><div class="label">Housekeeping</div></div>
+ <div class="stat-card good"><div class="num">90%</div><div class="label">AI Layer</div></div>
+ <div class="stat-card warn"><div class="num">60%</div><div class="label">Agent Ecosystem</div></div>
+</div>
+
+<p style="color:#8899aa; margin-top:1rem;">
+<strong>Overall: 68/100 β€” Functional but fragile.</strong> The core AI and module layers are solid, but the VFS layer has two critical data-loss bugs and significant structural debt. The agent ecosystem is dormant (12 registered, 0 active). Housekeeping is the weakest area β€” stale artifacts, empty directories, and orphaned metadata accumulate without cleanup.
+</p>
+
+<div class="footer">
+ newOS4 v4.5.83 Β· Architecture Audit Β· 2026-07-03 16:14 UTC Β· Generated by Architect Role
+</div>
+
+</body>
+</html>
+``` \ No newline at end of file
diff --git a/downloads/memory/newos-architecture-3d.html b/downloads/memory/newos-architecture-3d.html
new file mode 100644
index 0000000..c1f30e5
--- /dev/null
+++ b/downloads/memory/newos-architecture-3d.html
@@ -0,0 +1,612 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
+<meta name="theme-color" content="#0a0e1a">
+<meta name="apple-mobile-web-app-capable" content="yes">
+<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
+<title>newOS4 Β· Mobile Architecture</title>
+<style>
+ *, *::before, *::after {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+ -webkit-tap-highlight-color: transparent;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ user-select: none;
+ }
+ html, body {
+ width: 100%;
+ height: 100%;
+ height: 100dvh;
+ overflow: hidden;
+ background: #0a0e1a;
+ color: #e8eef7;
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+ overscroll-behavior: none;
+ touch-action: none;
+ }
+ body {
+ position: fixed;
+ inset: 0;
+ background: radial-gradient(ellipse at center, #131a2c 0%, #0a0e1a 70%);
+ }
+ #scene {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ touch-action: none;
+ cursor: grab;
+ }
+ #scene.dragging { cursor: grabbing; }
+
+ /* HUD β€” top-left, always visible, big enough to read on phone */
+ #hud {
+ position: absolute;
+ top: max(env(safe-area-inset-top, 0px), 12px);
+ left: 12px;
+ z-index: 10;
+ pointer-events: none;
+ line-height: 1.35;
+ }
+ #hud .title {
+ font-size: 16px;
+ font-weight: 700;
+ letter-spacing: 0.3px;
+ color: #7dd3fc;
+ text-shadow: 0 0 8px rgba(125, 211, 252, 0.4);
+ }
+ #hud .sub {
+ font-size: 12px;
+ font-weight: 500;
+ color: #94a3b8;
+ margin-top: 2px;
+ }
+ #hud .hint {
+ font-size: 11px;
+ color: #64748b;
+ margin-top: 6px;
+ max-width: 220px;
+ }
+
+ /* Node info card β€” top-right, big text */
+ #card {
+ position: absolute;
+ top: max(env(safe-area-inset-top, 0px), 12px);
+ right: 12px;
+ z-index: 20;
+ max-width: min(78vw, 320px);
+ background: rgba(15, 22, 38, 0.92);
+ border: 1px solid rgba(125, 211, 252, 0.35);
+ border-radius: 12px;
+ padding: 14px 16px;
+ backdrop-filter: blur(10px);
+ -webkit-backdrop-filter: blur(10px);
+ box-shadow: 0 10px 30px rgba(0,0,0,0.4), 0 0 0 1px rgba(125,211,252,0.08) inset;
+ pointer-events: none;
+ transform: translateX(20px);
+ opacity: 0;
+ transition: transform 0.18s ease-out, opacity 0.18s ease-out;
+ }
+ #card.visible {
+ transform: translateX(0);
+ opacity: 1;
+ }
+ #card .name {
+ font-size: 18px;
+ font-weight: 700;
+ color: #fff;
+ margin-bottom: 4px;
+ }
+ #card .layer {
+ display: inline-block;
+ font-size: 11px;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.8px;
+ padding: 3px 8px;
+ border-radius: 4px;
+ margin-bottom: 8px;
+ }
+ #card .desc {
+ font-size: 14px;
+ line-height: 1.45;
+ color: #cbd5e1;
+ }
+ #card .close {
+ position: absolute;
+ top: 8px;
+ right: 8px;
+ width: 24px;
+ height: 24px;
+ border-radius: 12px;
+ background: rgba(255,255,255,0.08);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+ color: #94a3b8;
+ pointer-events: auto;
+ cursor: pointer;
+ }
+
+ /* Control bar β€” bottom-center, big touch targets */
+ #controls {
+ position: absolute;
+ bottom: max(env(safe-area-inset-bottom, 0px), 16px);
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 10;
+ display: flex;
+ gap: 8px;
+ padding: 8px;
+ background: rgba(15, 22, 38, 0.75);
+ border: 1px solid rgba(255,255,255,0.08);
+ border-radius: 32px;
+ backdrop-filter: blur(10px);
+ -webkit-backdrop-filter: blur(10px);
+ }
+ .btn {
+ width: 44px;
+ height: 44px;
+ border-radius: 22px;
+ background: rgba(255,255,255,0.05);
+ border: 1px solid rgba(255,255,255,0.08);
+ color: #cbd5e1;
+ font-size: 18px;
+ font-weight: 600;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: pointer;
+ transition: background 0.15s, transform 0.1s;
+ }
+ .btn:active {
+ background: rgba(125, 211, 252, 0.2);
+ transform: scale(0.92);
+ }
+ .btn.active {
+ background: rgba(125, 211, 252, 0.18);
+ color: #7dd3fc;
+ border-color: rgba(125, 211, 252, 0.4);
+ }
+
+ /* Status β€” bottom-left */
+ #status {
+ position: absolute;
+ bottom: max(env(safe-area-inset-bottom, 0px), 24px);
+ left: 12px;
+ z-index: 10;
+ font-size: 11px;
+ color: #64748b;
+ pointer-events: none;
+ }
+ #status .dot {
+ display: inline-block;
+ width: 6px;
+ height: 6px;
+ border-radius: 3px;
+ background: #22c55e;
+ margin-right: 6px;
+ vertical-align: middle;
+ box-shadow: 0 0 6px #22c55e;
+ }
+
+ /* SVG node label β€” big, never tiny */
+ .label {
+ font-size: 13px;
+ font-weight: 600;
+ fill: #e2e8f0;
+ paint-order: stroke;
+ stroke: #0a0e1a;
+ stroke-width: 3px;
+ stroke-linejoin: round;
+ pointer-events: none;
+ text-anchor: middle;
+ dominant-baseline: middle;
+ }
+ .label.sub {
+ font-size: 10px;
+ font-weight: 500;
+ fill: #94a3b8;
+ }
+ .node-hit {
+ cursor: pointer;
+ transition: opacity 0.15s;
+ }
+ .node-hit.pinned {
+ opacity: 1;
+ }
+ .node-circle {
+ transition: r 0.15s, filter 0.15s;
+ }
+ .node-circle.pinned {
+ filter: drop-shadow(0 0 6px currentColor);
+ }
+
+ /* Pulse animation overlay (CSS, fires once on demand) */
+ @keyframes pulseRing {
+ 0% { transform: scale(0.6); opacity: 0.9; }
+ 100% { transform: scale(2.4); opacity: 0; }
+ }
+ .pulse-ring {
+ position: absolute;
+ width: 80px;
+ height: 80px;
+ border-radius: 50%;
+ border: 2px solid #7dd3fc;
+ pointer-events: none;
+ animation: pulseRing 1.2s ease-out forwards;
+ z-index: 5;
+ }
+</style>
+</head>
+<body>
+
+<div id="hud">
+ <div class="title">newOS4</div>
+ <div class="sub">41 modules Β· 24 skills Β· 303 files</div>
+ <div class="hint">Drag to orbit Β· Tap a node</div>
+</div>
+
+<div id="card">
+ <div class="close" id="cardClose">Γ—</div>
+ <div class="layer" id="cardLayer">CORE</div>
+ <div class="name" id="cardName">β€”</div>
+ <div class="desc" id="cardDesc">β€”</div>
+</div>
+
+<div id="controls">
+ <button class="btn" id="btnReset" title="Reset view">βŒ‚</button>
+ <button class="btn" id="btnPulse" title="Pulse">~</button>
+ <button class="btn" id="btnLabels" title="Toggle labels">A</button>
+ <button class="btn" id="btnFlows" title="Toggle flows">β—‰</button>
+ <button class="btn" id="btnHelp" title="Help">?</button>
+</div>
+
+<div id="status"><span class="dot"></span><span id="statusText">idle</span></div>
+
+<svg id="scene" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 700" preserveAspectRatio="xMidYMid meet">
+ <defs>
+ <radialGradient id="bgGrad" cx="50%" cy="50%" r="70%">
+ <stop offset="0%" stop-color="#1a2440" stop-opacity="0.6"/>
+ <stop offset="100%" stop-color="#0a0e1a" stop-opacity="0"/>
+ </radialGradient>
+ <filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
+ <feGaussianBlur stdDeviation="2" result="blur"/>
+ <feMerge>
+ <feMergeNode in="blur"/>
+ <feMergeNode in="SourceGraphic"/>
+ </feMerge>
+ </filter>
+ </defs>
+
+ <!-- Star field (static, cheap) -->
+ <g id="stars" opacity="0.6"></g>
+
+ <!-- Background gradient overlay -->
+ <rect x="0" y="0" width="400" height="700" fill="url(#bgGrad)" pointer-events="none"/>
+
+ <!-- Edges layer -->
+ <g id="edges" fill="none" stroke-linecap="round"></g>
+
+ <!-- Nodes layer -->
+ <g id="nodes"></g>
+
+ <!-- Labels layer -->
+ <g id="labels"></g>
+</svg>
+
+<script>
+(() => {
+ 'use strict';
+
+ // ---------- DATA ----------
+ const layers = {
+ core: { color: '#7dd3fc', name: 'Core', y: 90 },
+ ai: { color: '#a78bfa', name: 'AI Engine', y: 200 },
+ ext: { color: '#34d399', name: 'Extensions', y: 310 },
+ user: { color: '#fbbf24', name: 'User Space', y: 430 },
+ world: { color: '#f472b6', name: 'World Model', y: 560 },
+ };
+
+ const nodes = [
+ // Core
+ { id: 'kernel', layer: 'core', label: 'Kernel', x: 200, r: 22 },
+ { id: 'vfs', layer: 'core', label: 'VFS', x: 110, r: 18 },
+ { id: 'modules', layer: 'core', label: 'Modules', x: 290, r: 18 },
+ { id: 'skills', layer: 'core', label: 'Skills', x: 60, r: 16 },
+ { id: 'agents', layer: 'core', label: 'Agents', x: 340, r: 16 },
+
+ // AI
+ { id: 'llm', layer: 'ai', label: 'LLM', x: 200, r: 22 },
+ { id: 'router', layer: 'ai', label: 'Router', x: 100, r: 17 },
+ { id: 'memory', layer: 'ai', label: 'Memory', x: 300, r: 18 },
+ { id: 'tools', layer: 'ai', label: 'Tools', x: 40, r: 15 },
+ { id: 'prompts', layer: 'ai', label: 'Prompts', x: 360, r: 15 },
+
+ // Extensions
+ { id: 'wallet', layer: 'ext', label: 'Wallet', x: 150, r: 20 },
+ { id: 'wpm', layer: 'ext', label: 'WPM', x: 270, r: 17 },
+ { id: 'webdav', layer: 'ext', label: 'WebDAV', x: 60, r: 16 },
+ { id: 'cron', layer: 'ext', label: 'Cron', x: 340, r: 16 },
+ { id: 'sandbox', layer: 'ext', label: 'Sandbox', x: 220, r: 15 },
+
+ // User
+ { id: 'profile', layer: 'user', label: 'Profile', x: 100, r: 17 },
+ { id: 'sessions', layer: 'user', label: 'Sessions', x: 220, r: 18 },
+ { id: 'vault', layer: 'user', label: 'Vault', x: 320, r: 17 },
+
+ // World Model
+ { id: 'wm', layer: 'world', label: 'WorldModel', x: 200, r: 22 },
+ { id: 'graph', layer: 'world', label: 'Graph', x: 100, r: 17 },
+ { id: 'predict', layer: 'world', label: 'Predict', x: 300, r: 18 },
+ ];
+
+ const descs = {
+ kernel: 'System core. Mounts modules, routes commands, owns the event loop.',
+ vfs: 'Virtual filesystem. Resolves paths, lists dirs, reads/writes files.',
+ modules: '41 modules loaded. Core + extension. Hot-reloadable.',
+ skills: '24 markdown skills. Searchable, patchable, versioned.',
+ agents: '3 worker agents. Delegate tasks with capabilities.',
+ llm: 'MiniMax-M3 by MiniMax. Coding-tuned, 2026-01 cutoff.',
+ router: 'Routes tool calls to the right module. Zero-fallback chain.',
+ memory: '37 nodes, 51 edges in the memory graph. Auto-pruned.',
+ tools: '21 tools: read/write, modules, web, vault, agents.',
+ prompts: 'System + per-task prompts. Editable via edit_module.',
+ wallet: 'Wallet lookup, no auth. Read-only Hyperliquid queries.',
+ wpm: 'WebX11 Package Manager. Install modules with one command.',
+ webdav: 'Remote filesystem. Mount, browse, edit over HTTPS.',
+ cron: 'Scheduled tasks. Cron expressions in skill files.',
+ sandbox: 'Isolated JS execution. node -e, browser JS only.',
+ profile: 'User preferences. preferredModel, history, settings.',
+ sessions: 'Session save/load. Date-keyed, terminal-aware.',
+ vault: 'Secret vault. Hyperliquid keys, API tokens, encrypted.',
+ wm: 'Self-awareness model. Ask about state, health, projects.',
+ graph: 'Knowledge graph. 37 nodes linking tasks to files.',
+ predict: 'Predict task duration, tokens, confidence. ML-trained.',
+ };
+
+ const edges = [
+ ['kernel','vfs'], ['kernel','modules'], ['kernel','skills'], ['kernel','agents'],
+ ['llm','router'], ['llm','memory'], ['llm','tools'], ['llm','prompts'],
+ ['modules','wallet'], ['modules','wpm'], ['modules','webdav'], ['modules','cron'], ['modules','sandbox'],
+ ['profile','sessions'], ['profile','vault'],
+ ['wm','graph'], ['wm','predict'],
+ ['llm','wm'], ['kernel','llm'],
+ ];
+
+ // ---------- RENDER ----------
+ const svg = document.getElementById('scene');
+ const starsG = document.getElementById('stars');
+ const edgesG = document.getElementById('edges');
+ const nodesG = document.getElementById('nodes');
+ const labelsG = document.getElementById('labels');
+ const card = document.getElementById('card');
+ const cardName = document.getElementById('cardName');
+ const cardDesc = document.getElementById('cardDesc');
+ const cardLayer = document.getElementById('cardLayer');
+ const cardClose = document.getElementById('cardClose');
+ const statusText = document.getElementById('statusText');
+
+ // Stars
+ (function makeStars() {
+ let s = '';
+ for (let i = 0; i < 60; i++) {
+ const x = Math.random() * 400;
+ const y = Math.random() * 700;
+ const r = Math.random() * 0.8 + 0.3;
+ const o = Math.random() * 0.6 + 0.2;
+ s += `<circle cx="${x.toFixed(1)}" cy="${y.toFixed(1)}" r="${r.toFixed(2)}" fill="#cbd5e1" opacity="${o.toFixed(2)}"/>`;
+ }
+ starsG.innerHTML = s;
+ })();
+
+ // Edges
+ const nodeMap = Object.fromEntries(nodes.map(n => [n.id, n]));
+ let edgeHTML = '';
+ edges.forEach(([a, b]) => {
+ const na = nodeMap[a], nb = nodeMap[b];
+ if (!na || !nb) return;
+ const la = layers[na.layer], lb = layers[nb.layer];
+ const c = la.color;
+ const opacity = (la === lb) ? 0.45 : 0.3;
+ edgeHTML += `<line x1="${na.x}" y1="${la.y}" x2="${nb.x}" y2="${lb.y}" stroke="${c}" stroke-width="1.2" opacity="${opacity}"/>`;
+ });
+ edgesG.innerHTML = edgeHTML;
+
+ // Nodes
+ let nodeHTML = '';
+ let labelHTML = '';
+ let showLabels = true;
+ let showFlows = true;
+ nodes.forEach(n => {
+ const L = layers[n.layer];
+ nodeHTML += `
+ <g class="node-hit" data-id="${n.id}">
+ <circle class="node-circle" cx="${n.x}" cy="${L.y}" r="${n.r}" fill="${L.color}" fill-opacity="0.18" stroke="${L.color}" stroke-width="2" filter="url(#glow)"/>
+ </g>`;
+ labelHTML += `<text class="label" x="${n.x}" y="${L.y + n.r + 14}">${n.label}</text>`;
+ });
+ nodesG.innerHTML = nodeHTML;
+ labelsG.innerHTML = labelHTML;
+
+ // ---------- INTERACTION ----------
+ let pinned = null;
+ let camYaw = 0; // -1..1 mapped to dx
+ let dragging = false;
+ let dragStart = null;
+ let lastTap = null;
+
+ function setStatus(t) { statusText.textContent = t; }
+
+ function showCard(id) {
+ const n = nodeMap[id];
+ if (!n) return;
+ const L = layers[n.layer];
+ cardName.textContent = n.label;
+ cardDesc.textContent = descs[id] || '';
+ cardLayer.textContent = L.name;
+ cardLayer.style.background = L.color;
+ cardLayer.style.color = '#0a0e1a';
+ card.classList.add('visible');
+ setStatus('viewing ' + n.label);
+
+ // Highlight node
+ document.querySelectorAll('.node-circle').forEach(c => c.classList.remove('pinned'));
+ document.querySelectorAll('.node-hit').forEach(g => g.classList.remove('pinned'));
+ const hit = document.querySelector(`.node-hit[data-id="${id}"]`);
+ if (hit) {
+ hit.classList.add('pinned');
+ hit.querySelector('.node-circle').classList.add('pinned');
+ }
+ pinned = id;
+ }
+
+ function hideCard() {
+ card.classList.remove('visible');
+ document.querySelectorAll('.node-circle').forEach(c => c.classList.remove('pinned'));
+ document.querySelectorAll('.node-hit').forEach(g => g.classList.remove('pinned'));
+ pinned = null;
+ setStatus('idle');
+ }
+
+ cardClose.addEventListener('click', (e) => {
+ e.stopPropagation();
+ hideCard();
+ });
+
+ // Find node by touch/click coordinates
+ function hitTest(clientX, clientY) {
+ const rect = svg.getBoundingClientRect();
+ // Map client coords into viewBox 400x700
+ const x = (clientX - rect.left) * (400 / rect.width);
+ const y = (clientY - rect.top) * (700 / rect.height);
+ let best = null, bestD = Infinity;
+ for (const n of nodes) {
+ const ny = layers[n.layer].y;
+ const dx = x - n.x, dy = y - ny;
+ const d = Math.sqrt(dx*dx + dy*dy);
+ // Big hit radius on mobile (24-32)
+ const hr = Math.max(n.r + 14, 24);
+ if (d < hr && d < bestD) { bestD = d; best = n; }
+ }
+ return best;
+ }
+
+ // Camera orbit (horizontal drag only β€” most natural on phone)
+ function applyCamera() {
+ const maxDx = 25;
+ const dx = camYaw * maxDx;
+ edgesG.setAttribute('transform', `translate(${dx} 0)`);
+ nodesG.setAttribute('transform', `translate(${dx} 0)`);
+ labelsG.setAttribute('transform', `translate(${dx} 0)`);
+ }
+
+ function onPointerDown(e) {
+ dragging = true;
+ svg.classList.add('dragging');
+ const t = (e.touches ? e.touches[0] : e);
+ dragStart = { x: t.clientX, y: t.clientY, t: Date.now(), dx: 0, dy: 0 };
+ setStatus('dragging');
+ }
+
+ function onPointerMove(e) {
+ if (!dragging) return;
+ e.preventDefault();
+ const t = (e.touches ? e.touches[0] : e);
+ dragStart.dx = t.clientX - dragStart.x;
+ dragStart.dy = t.clientY - dragStart.y;
+ // Map horizontal drag to yaw (-1..1)
+ camYaw = Math.max(-1, Math.min(1, dragStart.dx / 120));
+ applyCamera();
+ }
+
+ function onPointerUp(e) {
+ if (!dragging) return;
+ dragging = false;
+ svg.classList.remove('dragging');
+ const moved = Math.abs(dragStart.dx) + Math.abs(dragStart.dy);
+ const dt = Date.now() - dragStart.t;
+ // Tap = small movement, short time
+ if (moved < 8 && dt < 400) {
+ const t = (e.changedTouches ? e.changedTouches[0] : e);
+ const hit = hitTest(t.clientX, t.clientY);
+ if (hit) {
+ if (pinned === hit.id) hideCard();
+ else showCard(hit.id);
+ } else {
+ hideCard();
+ }
+ } else {
+ setStatus('idle');
+ }
+ }
+
+ // Touch
+ svg.addEventListener('touchstart', (e) => { onPointerDown(e); }, { passive: false });
+ svg.addEventListener('touchmove', (e) => { onPointerMove(e); }, { passive: false });
+ svg.addEventListener('touchend', (e) => { onPointerUp(e); }, { passive: false });
+ svg.addEventListener('touchcancel',(e) => { dragging = false; svg.classList.remove('dragging'); setStatus('idle'); });
+
+ // Mouse (desktop fallback)
+ svg.addEventListener('mousedown', onPointerDown);
+ window.addEventListener('mousemove', onPointerMove);
+ window.addEventListener('mouseup', onPointerUp);
+
+ // Pinch zoom (simple)
+ let pinchStart = 0;
+ svg.addEventListener('gesturestart', (e) => { pinchStart = e.scale; });
+ svg.addEventListener('gesturechange', (e) => {
+ const s = e.scale / pinchStart;
+ svg.style.transform = `scale(${Math.max(0.6, Math.min(2, s))})`;
+ svg.style.transformOrigin = 'center center';
+ });
+
+ // ---------- CONTROLS ----------
+ document.getElementById('btnReset').addEventListener('click', () => {
+ camYaw = 0; applyCamera();
+ svg.style.transform = '';
+ hideCard();
+ });
+
+ document.getElementById('btnPulse').addEventListener('click', (e) => {
+ const r = e.currentTarget.getBoundingClientRect();
+ const ring = document.createElement('div');
+ ring.className = 'pulse-ring';
+ ring.style.left = (r.left + r.width/2 - 40) + 'px';
+ ring.style.top = (r.top + r.height/2 - 40) + 'px';
+ document.body.appendChild(ring);
+ setTimeout(() => ring.remove(), 1300);
+ setStatus('pulse');
+ setTimeout(() => { if (!pinned) setStatus('idle'); }, 1200);
+ });
+
+ document.getElementById('btnLabels').addEventListener('click', (e) => {
+ showLabels = !showLabels;
+ labelsG.style.display = showLabels ? '' : 'none';
+ e.currentTarget.classList.toggle('active', showLabels);
+ });
+ document.getElementById('btnLabels').classList.add('active');
+
+ document.getElementById('btnFlows').addEventListener('click', (e) => {
+ showFlows = !showFlows;
+ edgesG.style.display = showFlows ? '' : 'none';
+ e.currentTarget.classList.toggle('active', showFlows);
+ });
+ document.getElementById('btnFlows').classList.add('active');
+
+ document.getElementById('btnHelp').addEventListener('click', () => {
+ showCard('kernel');
+ });
+
+ // Initial status
+ setStatus('idle');
+})();
+</script>
+
+</body>
+</html>
diff --git a/downloads/memory/release-arc-3d.html b/downloads/memory/release-arc-3d.html
new file mode 100644
index 0000000..2aa359d
--- /dev/null
+++ b/downloads/memory/release-arc-3d.html
@@ -0,0 +1,384 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<title>newOS4 Memory Constellation β€” v4.5.86 β†’ v4.5.90b</title>
+<style>
+ html,body { margin:0; padding:0; background:#02030a; color:#cfe; font-family:ui-monospace,Menlo,monospace; overflow:hidden; }
+ #app { position:fixed; inset:0; }
+ #hud { position:fixed; top:12px; left:12px; padding:10px 14px; background:rgba(0,0,0,.55); border:1px solid #234; border-radius:6px; max-width:320px; font-size:12px; line-height:1.5; backdrop-filter:blur(6px); }
+ #hud h1 { margin:0 0 6px; font-size:14px; color:#9ef; letter-spacing:.5px; }
+ #hud .row { display:flex; justify-content:space-between; gap:12px; }
+ #hud .k { color:#678; } #hud .v { color:#bdf; }
+ #info { position:fixed; bottom:12px; left:12px; padding:10px 14px; background:rgba(0,0,0,.55); border:1px solid #234; border-radius:6px; max-width:420px; font-size:12px; line-height:1.55; backdrop-filter:blur(6px); display:none; }
+ #info .ver { color:#fff; font-weight:700; }
+ #info .phase { color:#9ef; font-size:10px; text-transform:uppercase; letter-spacing:1px; }
+ #info ul { margin:6px 0 0; padding-left:16px; color:#9ab; }
+ #controls { position:fixed; top:12px; right:12px; display:flex; flex-direction:column; gap:6px; }
+ #controls button { background:rgba(0,0,0,.6); color:#9ef; border:1px solid #234; padding:6px 10px; font-family:inherit; font-size:11px; border-radius:4px; cursor:pointer; }
+ #controls button:hover { background:rgba(40,80,120,.5); }
+ #legend { position:fixed; bottom:12px; right:12px; padding:8px 12px; background:rgba(0,0,0,.55); border:1px solid #234; border-radius:6px; font-size:11px; }
+ #legend .item { display:flex; align-items:center; gap:6px; margin:2px 0; color:#9ab; }
+ #legend .dot { width:8px; height:8px; border-radius:50%; }
+ #tip { position:fixed; bottom:6px; left:50%; transform:translateX(-50%); color:#456; font-size:10px; letter-spacing:1px; }
+</style>
+</head>
+<body>
+<div id="app"></div>
+<div id="hud">
+ <h1>β—‰ newOS4 MEMORY CONSTELLATION</h1>
+ <div class="row"><span class="k">range</span><span class="v">v4.5.86 β†’ v4.5.90b</span></div>
+ <div class="row"><span class="k">releases</span><span class="v">7</span></div>
+ <div class="row"><span class="k">modules</span><span class="v">43</span></div>
+ <div class="row"><span class="k">skills</span><span class="v">24</span></div>
+ <div class="row"><span class="k">review findings</span><span class="v">12 closed</span></div>
+ <div class="row"><span class="k">status</span><span class="v">βœ… shipped clean</span></div>
+</div>
+<div id="info"></div>
+<div id="controls">
+ <button id="b-rot">⏸ auto-rotate</button>
+ <button id="b-pulse">β—Œ trigger pulse</button>
+ <button id="b-reset">βŒ– reset view</button>
+</div>
+<div id="legend">
+ <div class="item"><span class="dot" style="background:#4488ff"></span>v4.5.86 cold-start</div>
+ <div class="item"><span class="dot" style="background:#44ddff"></span>v4.5.87 purge</div>
+ <div class="item"><span class="dot" style="background:#44ffaa"></span>v4.5.88 schema</div>
+ <div class="item"><span class="dot" style="background:#88ff44"></span>v4.5.89 connectors</div>
+ <div class="item"><span class="dot" style="background:#ffee44"></span>v4.5.89b review</div>
+ <div class="item"><span class="dot" style="background:#ff9944"></span>v4.5.90 skills</div>
+ <div class="item"><span class="dot" style="background:#ff4488"></span>v4.5.90b skill-review</div>
+</div>
+<div id="tip">drag to rotate Β· scroll to zoom Β· click a node</div>
+
+<script type="importmap">
+{
+ "imports": {
+ "three": "https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js",
+ "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/"
+ }
+}
+</script>
+
+<script type="module">
+import * as THREE from 'three';
+import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
+
+// ─── SCENE SETUP ─────────────────────────────────────────────────────────
+const app = document.getElementById('app');
+const scene = new THREE.Scene();
+scene.fog = new THREE.FogExp2(0x02030a, 0.012);
+
+const camera = new THREE.PerspectiveCamera(55, innerWidth/innerHeight, 0.1, 200);
+camera.position.set(12, 8, 16);
+
+const renderer = new THREE.WebGLRenderer({ antialias:true, alpha:false });
+renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
+renderer.setSize(innerWidth, innerHeight);
+renderer.setClearColor(0x02030a);
+app.appendChild(renderer.domElement);
+
+const controls = new OrbitControls(camera, renderer.domElement);
+controls.enableDamping = true;
+controls.dampingFactor = 0.06;
+controls.minDistance = 6;
+controls.maxDistance = 40;
+const initialCam = camera.position.clone();
+
+// ─── LIGHTING ────────────────────────────────────────────────────────────
+scene.add(new THREE.HemisphereLight(0x6688aa, 0x110022, 0.55));
+const key = new THREE.DirectionalLight(0xffeebb, 1.1); key.position.set(8, 12, 6); scene.add(key);
+const fill = new THREE.PointLight(0x4488ff, 1.4, 30); fill.position.set(-8, 4, -6); scene.add(fill);
+const rim = new THREE.PointLight(0xff4488, 0.9, 24); rim.position.set(6, 8, -10); scene.add(rim);
+
+// ─── RELEASE DATA (hand-calculated helix positions) ─────────────────────
+// Helix: 7 points, R=4.2, y-step=1.4, angle = i * 2Ο€/6
+// x = R*cos(ΞΈ), z = R*sin(ΞΈ), y = i*1.4 - 4.2 (centered vertically)
+const R = 4.2, STEP = 1.4, OFFSET_Y = -4.2;
+const cos = (a)=>Math.cos(a), sin=(a)=>Math.sin(a);
+const angle = (i)=>i * (Math.PI*2/6);
+const yOf = (i)=>i * STEP + OFFSET_Y;
+
+const releases = [
+ { v:'v4.5.86', phase:'Cold-Start', color:0x4488ff, size:0.55, info:[
+ 'Activated 3 dormant modules',
+ 'Predictor, MemoryGraph, WorldModel',
+ 'First runnable cognitive stack']},
+ { v:'v4.5.87', phase:'Purge + Slim', color:0x44ddff, size:0.50, info:[
+ '-42% system prompt',
+ 'Removed dead code',
+ 'Smaller, faster, focused']},
+ { v:'v4.5.88', phase:'Schema 2.0', color:0x44ffaa, size:0.55, info:[
+ 'Namespace: global vs agent',
+ 'source_session field',
+ 'Dual-lookup (by id + by query)']},
+ { v:'v4.5.89', phase:'Connectors', color:0x88ff44, size:0.62, info:[
+ 'memgraph ↔ NVFS bridge',
+ 'World-model TTL + refresh',
+ 'Lazy decay, semantic sync']},
+ { v:'v4.5.89b', phase:'Review Harden', color:0xffee44, size:0.58, info:[
+ '6 review findings fixed',
+ 'Config persistence',
+ 'Clean before R3']},
+ { v:'v4.5.90', phase:'Agent Skills', color:0xff9944, size:0.78, info:[
+ '4 commands: learn, validate, audit, restore',
+ '8 methods exposed',
+ 'Skills self-improve']},
+ { v:'v4.5.90b', phase:'Skill Review', color:0xff4488, size:0.85, info:[
+ '6 more findings closed',
+ 'Bayesian confidence (uses/(uses+5))',
+ '0 P0/P1 outstanding']},
+];
+
+// ─── GLOW TEXTURE (canvas-based radial gradient) ────────────────────────
+function glowTexture(inner, outer){
+ const c = document.createElement('canvas'); c.width = c.height = 128;
+ const ctx = c.getContext('2d');
+ const g = ctx.createRadialGradient(64,64,0, 64,64,64);
+ g.addColorStop(0, inner); g.addColorStop(0.4, outer); g.addColorStop(1, 'rgba(0,0,0,0)');
+ ctx.fillStyle = g; ctx.fillRect(0,0,128,128);
+ return new THREE.CanvasTexture(c);
+}
+
+// ─── CENTRAL CORE ────────────────────────────────────────────────────────
+const coreGeo = new THREE.IcosahedronGeometry(1.1, 1);
+const coreMat = new THREE.MeshPhongMaterial({ color:0xffffff, emissive:0x4488ff, emissiveIntensity:0.6, shininess:80, flatShading:true });
+const core = new THREE.Mesh(coreGeo, coreMat);
+scene.add(core);
+
+// core glow halo
+const coreGlow = new THREE.Sprite(new THREE.SpriteMaterial({ map: glowTexture('rgba(120,180,255,0.9)','rgba(40,80,180,0.4)'), blending:THREE.AdditiveBlending, depthWrite:false }));
+coreGlow.scale.set(5,5,5);
+scene.add(coreGlow);
+
+// ─── RELEASE NODES ───────────────────────────────────────────────────────
+const releaseGroup = new THREE.Group();
+scene.add(releaseGroup);
+
+const releaseMeshes = [];
+releases.forEach((r, i) => {
+ const a = angle(i);
+ const pos = new THREE.Vector3(R*cos(a), yOf(i), R*sin(a));
+
+ // sphere
+ const geo = new THREE.SphereGeometry(r.size, 32, 32);
+ const mat = new THREE.MeshPhongMaterial({ color: r.color, emissive: r.color, emissiveIntensity: 0.35, shininess:60 });
+ const mesh = new THREE.Mesh(geo, mat);
+ mesh.position.copy(pos);
+ mesh.userData = r;
+ releaseGroup.add(mesh);
+ releaseMeshes.push(mesh);
+
+ // glow sprite
+ const glow = new THREE.Sprite(new THREE.SpriteMaterial({ map: glowTexture('rgba(255,255,255,0.5)','rgba(0,0,0,0)'), color: r.color, blending:THREE.AdditiveBlending, depthWrite:false, transparent:true, opacity:0.7 }));
+ glow.scale.set(r.size*3.5, r.size*3.5, 1);
+ glow.position.copy(pos);
+ releaseGroup.add(glow);
+
+ // label sprite (canvas-baked text)
+ const lc = document.createElement('canvas'); lc.width=256; lc.height=64;
+ const lctx = lc.getContext('2d');
+ lctx.font='bold 28px ui-monospace,monospace';
+ lctx.textAlign='center'; lctx.textBaseline='middle';
+ lctx.fillStyle = '#' + r.color.toString(16).padStart(6,'0');
+ lctx.shadowColor='#000'; lctx.shadowBlur=6;
+ lctx.fillText(r.v, 128, 32);
+ const labelTex = new THREE.CanvasTexture(lc);
+ const label = new THREE.Sprite(new THREE.SpriteMaterial({ map: labelTex, depthWrite:false, transparent:true }));
+ label.scale.set(2.0, 0.5, 1);
+ label.position.set(pos.x, pos.y + r.size + 0.35, pos.z);
+ releaseGroup.add(label);
+});
+
+// ─── EDGES (curves between consecutive releases + radial to core) ────────
+const edgeMat = new THREE.LineBasicMaterial({ color: 0x446688, transparent:true, opacity:0.55 });
+for (let i=0; i<releaseMeshes.length-1; i++){
+ const a = releaseMeshes[i].position, b = releaseMeshes[i+1].position;
+ // quadratic curve via midpoint + slight outward bulge
+ const mid = a.clone().add(b).multiplyScalar(0.5);
+ mid.add(new THREE.Vector3(0, 0.6, 0));
+ const curve = new THREE.QuadraticBezierCurve3(a, mid, b);
+ const pts = curve.getPoints(40).map(p => new THREE.Vector3(p.x, p.y, p.z));
+ const geo = new THREE.BufferGeometry().setFromPoints(pts);
+ releaseGroup.add(new THREE.Line(geo, edgeMat));
+}
+// radial spokes from each release to core
+for (const m of releaseMeshes){
+ const geo = new THREE.BufferGeometry().setFromPoints([m.position, new THREE.Vector3(0,0,0)]);
+ const line = new THREE.Line(geo, new THREE.LineDashedMaterial({ color:0x224466, dashSize:0.15, gapSize:0.1, transparent:true, opacity:0.4 }));
+ line.computeLineDistances();
+ releaseGroup.add(line);
+}
+
+// ─── SKILL ORBIT NODES (4 commands from v4.5.90) ────────────────────────
+const skills = [
+ { name:'skill-learn', color:0xffddaa },
+ { name:'skill-validate', color:0xaaffdd },
+ { name:'skill-audit', color:0xddaaff },
+ { name:'skill-restore', color:0xaadfff },
+];
+const skillOrbit = new THREE.Group();
+scene.add(skillOrbit);
+const skillMeshes = [];
+skills.forEach((s, i) => {
+ const a = i * (Math.PI*2/skills.length) + Math.PI/4;
+ const radius = 7.2;
+ const pos = new THREE.Vector3(radius*cos(a), yOf(5) + Math.sin(a)*1.5, radius*sin(a));
+ const geo = new THREE.OctahedronGeometry(0.35, 0);
+ const mat = new THREE.MeshPhongMaterial({ color: s.color, emissive:s.color, emissiveIntensity:0.4, flatShading:true });
+ const mesh = new THREE.Mesh(geo, mat);
+ mesh.position.copy(pos);
+ mesh.userData = { v:s.name, phase:'v4.5.90 command', color:s.color,
+ info:['Command shipped in v4.5.90','Part of Agent Skills bundle']};
+ skillOrbit.add(mesh);
+ skillMeshes.push(mesh);
+
+ const lc=document.createElement('canvas');lc.width=256;lc.height=48;
+ const lctx=lc.getContext('2d');
+ lctx.font='20px ui-monospace,monospace'; lctx.textAlign='center'; lctx.textBaseline='middle';
+ lctx.fillStyle='#cde'; lctx.shadowColor='#000'; lctx.shadowBlur=4;
+ lctx.fillText(s.name, 128, 24);
+ const label = new THREE.Sprite(new THREE.SpriteMaterial({ map: new THREE.CanvasTexture(lc), depthWrite:false, transparent:true }));
+ label.scale.set(1.6, 0.3, 1);
+ label.position.set(pos.x, pos.y+0.6, pos.z);
+ skillOrbit.add(label);
+});
+
+// ─── MEMORY PARTICLES (instanced points) ────────────────────────────────
+const N = 400;
+const partGeo = new THREE.BufferGeometry();
+const positions = new Float32Array(N*3);
+const phases = new Float32Array(N);
+for (let i=0; i<N; i++){
+ // random points in a torus shell
+ const theta = Math.random()*Math.PI*2;
+ const r = 9 + Math.random()*4;
+ const y = (Math.random()-0.5) * 14;
+ positions[i*3] = r*cos(theta);
+ positions[i*3+1] = y;
+ positions[i*3+2] = r*sin(theta);
+ phases[i] = Math.random()*Math.PI*2;
+}
+partGeo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
+partGeo.setAttribute('phase', new THREE.BufferAttribute(phases, 1));
+const partMat = new THREE.PointsMaterial({ color:0x88aaff, size:0.05, transparent:true, opacity:0.6, sizeAttenuation:true, depthWrite:false });
+const particles = new THREE.Points(partGeo, partMat);
+scene.add(particles);
+
+// ─── PULSE RING (decay visualization) ────────────────────────────────────
+const pulseGeo = new THREE.RingGeometry(0.5, 0.55, 64);
+const pulseMat = new THREE.MeshBasicMaterial({ color:0x88ddff, side:THREE.DoubleSide, transparent:true, opacity:0.7, depthWrite:false, blending:THREE.AdditiveBlending });
+const pulse = new THREE.Mesh(pulseGeo, pulseMat);
+pulse.rotation.x = -Math.PI/2;
+pulse.visible = false;
+scene.add(pulse);
+let pulseT = 0, pulsing = false;
+
+// ─── STARFIELD ───────────────────────────────────────────────────────────
+const starGeo = new THREE.BufferGeometry();
+const starPos = new Float32Array(1500*3);
+for (let i=0; i<1500; i++){
+ // sphere shell far out
+ const t = Math.random()*Math.PI*2;
+ const p = Math.acos(2*Math.random()-1);
+ const r = 60 + Math.random()*40;
+ starPos[i*3] = r*Math.sin(p)*cos(t);
+ starPos[i*3+1] = r*Math.cos(p);
+ starPos[i*3+2] = r*Math.sin(p)*sin(t);
+}
+starGeo.setAttribute('position', new THREE.BufferAttribute(starPos, 3));
+scene.add(new THREE.Points(starGeo, new THREE.PointsMaterial({ color:0xffffff, size:0.15, sizeAttenuation:true, transparent:true, opacity:0.7 })));
+
+// ─── RAYCASTER (click) ──────────────────────────────────────────────────
+const raycaster = new THREE.Raycaster();
+const mouse = new THREE.Vector2();
+const pickables = [...releaseMeshes, ...skillMeshes, core];
+const infoEl = document.getElementById('info');
+
+function showInfo(d){
+ if (!d){ infoEl.style.display='none'; return; }
+ const c = '#' + (d.color||0x88aaff).toString(16).padStart(6,'0');
+ infoEl.style.borderColor = c + '66';
+ infoEl.innerHTML = `<div class="phase">${d.phase||''}</div>
+ <div class="ver" style="color:${c}">${d.v}</div>
+ <ul>${(d.info||[]).map(x=>`<li>${x}</li>`).join('')}</ul>`;
+ infoEl.style.display = 'block';
+}
+window.addEventListener('click', (e) => {
+ mouse.x = (e.clientX/innerWidth)*2 - 1;
+ mouse.y = -(e.clientY/innerHeight)*2 + 1;
+ raycaster.setFromCamera(mouse, camera);
+ const hits = raycaster.intersectObjects(pickables, false);
+ if (hits.length){ showInfo(hits[0].object.userData); }
+ else { showInfo(null); }
+});
+
+// ─── HOVER CURSOR ───────────────────────────────────────────────────────
+window.addEventListener('mousemove', (e)=>{
+ mouse.x = (e.clientX/innerWidth)*2 - 1;
+ mouse.y = -(e.clientY/innerHeight)*2 + 1;
+ raycaster.setFromCamera(mouse, camera);
+ const hits = raycaster.intersectObjects(pickables, false);
+ renderer.domElement.style.cursor = hits.length ? 'pointer' : 'grab';
+});
+
+// ─── UI BUTTONS ──────────────────────────────────────────────────────────
+let autoRotate = true;
+document.getElementById('b-rot').onclick = () => {
+ autoRotate = !autoRotate;
+ document.getElementById('b-rot').textContent = autoRotate ? '⏸ auto-rotate' : 'β–Ά auto-rotate';
+};
+document.getElementById('b-pulse').onclick = () => { pulsing = true; pulseT = 0; pulse.visible = true; };
+document.getElementById('b-reset').onclick = () => {
+ camera.position.copy(initialCam);
+ controls.target.set(0,0,0);
+ controls.update();
+};
+
+// ─── RESIZE ──────────────────────────────────────────────────────────────
+window.addEventListener('resize', () => {
+ camera.aspect = innerWidth/innerHeight;
+ camera.updateProjectionMatrix();
+ renderer.setSize(innerWidth, innerHeight);
+});
+
+// ─── ANIMATION LOOP ──────────────────────────────────────────────────────
+const clock = new THREE.Clock();
+function tick(){
+ const dt = clock.getDelta();
+ const t = clock.elapsedTime;
+
+ if (autoRotate){
+ releaseGroup.rotation.y += dt * 0.08;
+ skillOrbit.rotation.y -= dt * 0.15;
+ }
+ core.rotation.y += dt * 0.4;
+ core.rotation.x += dt * 0.2;
+ coreGlow.material.opacity = 0.7 + 0.3*Math.sin(t*2);
+
+ // particle drift
+ const ppos = particles.geometry.attributes.position;
+ const ppha = particles.geometry.attributes.phase;
+ for (let i=0; i<N; i++){
+ const ph = ppha.array[i];
+ ppos.array[i*3+1] += Math.sin(t + ph) * 0.003;
+ }
+ ppos.needsUpdate = true;
+
+ // pulse animation
+ if (pulsing){
+ pulseT += dt;
+ const s = 0.5 + pulseT * 12;
+ pulse.scale.set(s, s, s);
+ pulseMat.opacity = Math.max(0, 0.8 - pulseT*0.6);
+ if (pulseT > 1.5){ pulsing = false; pulse.visible = false; }
+ }
+
+ controls.update();
+ renderer.render(scene, camera);
+ requestAnimationFrame(tick);
+}
+tick();
+</script>
+</body>
+</html>
diff --git a/downloads/system-analysis-report.html b/downloads/system-analysis-report.html
new file mode 100644
index 0000000..395a171
--- /dev/null
+++ b/downloads/system-analysis-report.html
@@ -0,0 +1,556 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>WebX11 System Analysis & Optimization Report</title>
+ <style>
+ :root {
+ --bg: #0a0f0a;
+ --surface: #0f1a0f;
+ --border: #1a3320;
+ --accent: #00ff41;
+ --accent-dim: #00cc33;
+ --accent-glow: rgba(0, 255, 65, 0.15);
+ --text: #e0ffe6;
+ --text-dim: #88aa88;
+ --warn: #ffcc00;
+ --danger: #ff4444;
+ --info: #44aaff;
+ }
+ * { box-sizing: border-box; }
+ body {
+ margin: 0; padding: 0;
+ background: var(--bg);
+ color: var(--text);
+ font-family: 'Segoe UI', system-ui, sans-serif;
+ line-height: 1.6;
+ }
+ header {
+ border-bottom: 1px solid var(--border);
+ padding: 2rem;
+ background: var(--surface);
+ position: sticky; top: 0; z-index: 10;
+ box-shadow: 0 4px 20px rgba(0,0,0,0.5);
+ }
+ header h1 {
+ margin: 0;
+ font-size: 1.6rem;
+ color: var(--accent);
+ text-shadow: 0 0 10px var(--accent-glow);
+ }
+ header .meta {
+ color: var(--text-dim);
+ font-size: 0.85rem;
+ margin-top: 0.25rem;
+ }
+ .container {
+ max-width: 1100px;
+ margin: 0 auto;
+ padding: 2rem;
+ }
+ .badge {
+ display: inline-block;
+ padding: 0.15rem 0.5rem;
+ border: 1px solid var(--accent);
+ color: var(--accent);
+ font-size: 0.7rem;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ margin-right: 0.5rem;
+ }
+ .badge.warn { border-color: var(--warn); color: var(--warn); }
+ .badge.danger { border-color: var(--danger); color: var(--danger); }
+ .badge.info { border-color: var(--info); color: var(--info); }
+
+ .grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+ gap: 1.5rem;
+ margin: 2rem 0;
+ }
+ .panel {
+ background: var(--surface);
+ border: 1px solid var(--border);
+ border-radius: 6px;
+ padding: 1.25rem;
+ transition: transform 0.2s, box-shadow 0.2s;
+ }
+ .panel:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 24px var(--accent-glow);
+ }
+ .panel h3 {
+ margin: 0 0 0.75rem;
+ font-size: 1rem;
+ color: var(--accent);
+ display: flex; align-items: center; gap: 0.5rem;
+ }
+ .panel .value {
+ font-size: 2rem;
+ font-weight: 700;
+ color: var(--text);
+ }
+ .panel .label {
+ font-size: 0.8rem;
+ color: var(--text-dim);
+ }
+
+ section {
+ margin: 3rem 0;
+ padding: 1.5rem;
+ background: var(--surface);
+ border-left: 3px solid var(--accent);
+ border-radius: 0 6px 6px 0;
+ }
+ section h2 {
+ margin-top: 0;
+ font-size: 1.25rem;
+ color: var(--accent);
+ }
+ section.critical { border-left-color: var(--danger); }
+ section.warning { border-left-color: var(--warn); }
+ section.info { border-left-color: var(--info); }
+
+ table {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 1rem 0;
+ font-size: 0.9rem;
+ }
+ th, td {
+ text-align: left;
+ padding: 0.6rem 0.75rem;
+ border-bottom: 1px solid var(--border);
+ }
+ th {
+ color: var(--accent);
+ font-weight: 600;
+ text-transform: uppercase;
+ font-size: 0.75rem;
+ letter-spacing: 0.05em;
+ }
+ td { color: var(--text); }
+ tr:hover td { background: rgba(0,255,65,0.04); }
+
+ .metric-row {
+ display: flex;
+ justify-content: space-between;
+ padding: 0.4rem 0;
+ border-bottom: 1px dashed var(--border);
+ font-size: 0.9rem;
+ }
+ .metric-row:last-child { border-bottom: none; }
+
+ .progress {
+ height: 6px;
+ background: #1a3320;
+ border-radius: 3px;
+ overflow: hidden;
+ margin-top: 0.5rem;
+ }
+ .progress-fill {
+ height: 100%;
+ background: var(--accent);
+ border-radius: 3px;
+ }
+ .progress-fill.warn { background: var(--warn); }
+ .progress-fill.danger { background: var(--danger); }
+
+ ul.improvements {
+ list-style: none;
+ padding: 0;
+ }
+ ul.improvements li {
+ padding: 0.75rem 0;
+ border-bottom: 1px solid var(--border);
+ display: flex;
+ gap: 1rem;
+ align-items: flex-start;
+ }
+ ul.improvements li:last-child { border-bottom: none; }
+ ul.improvements .num {
+ font-family: monospace;
+ color: var(--accent);
+ font-weight: 700;
+ min-width: 1.5rem;
+ }
+ ul.improvements strong { color: var(--text); }
+ ul.improvements p { margin: 0.25rem 0 0; color: var(--text-dim); font-size: 0.9rem; }
+
+ .tag {
+ font-size: 0.7rem;
+ padding: 0.1rem 0.4rem;
+ border: 1px solid var(--border);
+ border-radius: 3px;
+ color: var(--text-dim);
+ margin-right: 0.3rem;
+ }
+
+ footer {
+ text-align: center;
+ padding: 2rem;
+ color: var(--text-dim);
+ font-size: 0.8rem;
+ border-top: 1px solid var(--border);
+ margin-top: 2rem;
+ }
+
+ @media (max-width: 640px) {
+ .container { padding: 1rem; }
+ header { padding: 1rem; }
+ .grid { grid-template-columns: 1fr; }
+ }
+ </style>
+</head>
+<body>
+
+<header>
+ <h1>WebX11 newOS4 β€” System Analysis & Optimization Report</h1>
+ <div class="meta">
+ Generated: 2026-07-03 16:44 UTC &bull; Version: 4.5.82 &bull; Profile: Full Diagnostic
+ </div>
+</header>
+
+<div class="container">
+
+ <!-- Executive Summary -->
+ <section class="info">
+ <h2><span class="badge info">Summary</span> Executive Overview</h2>
+ <p>
+ The WebX11 newOS4 terminal is a mature, modular browser-based operating environment
+ running <strong>43 active modules</strong> (22 core + 21 ext) with a lean memory footprint
+ of <strong>48.1 MB</strong>. AI inference is routed through Ollama (<code>kimi-k2.6:cloud</code>).
+ The system demonstrates strong architectural depthβ€”featuring agent orchestration, neural VFS
+ indexing, predictive resource allocation, and a world-model synthesizerβ€”but several
+ high-value subsystems remain <em>underutilized</em>. This report identifies structural
+ inefficiencies and provides an actionable optimization roadmap.
+ </p>
+ </section>
+
+ <!-- Live Telemetry -->
+ <div class="grid">
+ <div class="panel">
+ <h3>Modules</h3>
+ <div class="value">43/45</div>
+ <div class="label">Loaded / Available</div>
+ <div class="progress"><div class="progress-fill" style="width:96%"></div></div>
+ </div>
+ <div class="panel">
+ <h3>Agents</h3>
+ <div class="value">0/12</div>
+ <div class="label">Active / Registered</div>
+ <div class="progress"><div class="progress-fill danger" style="width:0%"></div></div>
+ </div>
+ <div class="panel">
+ <h3>Skills</h3>
+ <div class="value">37</div>
+ <div class="label">Stored Procedures</div>
+ <div class="progress"><div class="progress-fill" style="width:74%"></div></div>
+ </div>
+ <div class="panel">
+ <h3>Memory</h3>
+ <div class="value">48.1 MB</div>
+ <div class="label">Heap Usage</div>
+ <div class="progress"><div class="progress-fill" style="width:24%"></div></div>
+ </div>
+ <div class="panel">
+ <h3>VFS Objects</h3>
+ <div class="value">39</div>
+ <div class="label">Files in Root</div>
+ <div class="progress"><div class="progress-fill warn" style="width:65%"></div></div>
+ </div>
+ <div class="panel">
+ <h3>Ollama</h3>
+ <div class="value" style="font-size:1.2rem">Cloud</div>
+ <div class="label">kimi-k2.6 via Proxy</div>
+ <div class="progress"><div class="progress-fill" style="width:88%"></div></div>
+ </div>
+ </div>
+
+ <!-- Subsystem Health -->
+ <section>
+ <h2><span class="badge">Health</span> Subsystem Diagnostic</h2>
+ <table>
+ <tr>
+ <th>Subsystem</th>
+ <th>Status</th>
+ <th>Observation</th>
+ <th>Severity</th>
+ </tr>
+ <tr>
+ <td>Core Modules</td>
+ <td><span class="badge">Healthy</span></td>
+ <td>All 22 core modules loaded; 0 local edits; no version conflicts.</td>
+ <td>β€”</td>
+ </tr>
+ <tr>
+ <td>Ext Modules</td>
+ <td><span class="badge">Healthy</span></td>
+ <td>21 ext modules active (Three.js, Media, Floating, Debug, etc.).</td>
+ <td>β€”</td>
+ </tr>
+ <tr>
+ <td>Agent Swarm</td>
+ <td><span class="badge danger">Idle</span></td>
+ <td>12 agents registered, 0 active. Most have read-only capabilities.</td>
+ <td>High</td>
+ </tr>
+ <tr>
+ <td>Neural VFS</td>
+ <td><span class="badge warn">Stagnant</span></td>
+ <td>Index exists (.semantic_index) but no recent reindex observed.</td>
+ <td>Medium</td>
+ </tr>
+ <tr>
+ <td>Memory Graph</td>
+ <td><span class="badge warn">Cold</span></td>
+ <td>Module loaded but not surfaced in UI or assistant context.</td>
+ <td>Medium</td>
+ </tr>
+ <tr>
+ <td>Predictor</td>
+ <td><span class="badge warn">Cold</span></td>
+ <td>predictor-status available; not integrated into task routing.</td>
+ <td>Medium</td>
+ </tr>
+ <tr>
+ <td>World Model</td>
+ <td><span class="badge warn">Cold</span></td>
+ <td>Global self-awareness synthesizer inactive; could boost AI coherence.</td>
+ <td>Medium</td>
+ </tr>
+ <tr>
+ <td>Cron / Scheduler</td>
+ <td><span class="badge warn">Dormant</span></td>
+ <td>CronModule loaded but no recurring jobs evident.</td>
+ <td>Low</td>
+ </tr>
+ <tr>
+ <td>Dashboard</td>
+ <td><span class="badge danger">Static</span></td>
+ <td>NEXUS v0.3.1 is hardcoded HTML; not wired to live system data.</td>
+ <td>High</td>
+ </tr>
+ <tr>
+ <td>Secret Vault</td>
+ <td><span class="badge">Healthy</span></td>
+ <td>Vault locked/unlock commands present; no exposure detected.</td>
+ <td>β€”</td>
+ </tr>
+ </table>
+ </section>
+
+ <!-- Root Analysis -->
+ <section class="warning">
+ <h2><span class="badge warn">VFS</span> Root Directory Hygiene</h2>
+ <p>
+ The VFS root contains <strong>39 entries</strong> including version artifacts
+ (<code>v4.5.80</code>, <code>v4.5.81</code>, <code>v4.5.82</code>), a standalone
+ <code>three.js</code> library, and scattered debug files. This clutter increases
+ cognitive load and slows semantic indexing.
+ </p>
+ <div class="metric-row">
+ <span>Version files in root</span>
+ <span class="badge warn">3 files</span>
+ </div>
+ <div class="metric-row">
+ <span>help.html size</span>
+ <span class="badge warn">135 KB (monolithic)</span>
+ </div>
+ <div class="metric-row">
+ <span>debug.log size</span>
+ <span class="badge warn">10 KB (growing, no rotation)</span>
+ </div>
+ <div class="metric-row">
+ <span>Unclassified files</span>
+ <span class="badge danger">three.js, vfs.txt, v4.5.80debug</span>
+ </div>
+ </section>
+
+ <!-- Skill Audit -->
+ <section>
+ <h2><span class="badge">Skills</span> Knowledge Base Audit</h2>
+ <p>
+ 37 skills are stored, but quality is inconsistent. Several entries have
+ <strong>empty descriptions</strong> and there is topical overlap (e.g., two mindmap guides).
+ </p>
+ <table>
+ <tr><th>Issue</th><th>Count</th><th>Examples</th></tr>
+ <tr>
+ <td>Empty descriptions</td>
+ <td>5</td>
+ <td>kernel-lifecycle, perf-regression, semantic-dependency, agent-loop-studio, memory-graph-update</td>
+ </tr>
+ <tr>
+ <td>Duplicate topics</td>
+ <td>2</td>
+ <td>mindmap-workflow + mindmap-user-guide</td>
+ </tr>
+ <tr>
+ <td>Orphaned tags</td>
+ <td>1</td>
+ <td>memory-graph-update has no tags</td>
+ </tr>
+ <tr>
+ <td>High-quality</td>
+ <td>29</td>
+ <td>Fully tagged, categorized, and dated</td>
+ </tr>
+ </table>
+ </section>
+
+ <!-- Recommendations -->
+ <section class="critical">
+ <h2><span class="badge danger">Action</span> Priority Improvements</h2>
+ <ul class="improvements">
+ <li>
+ <span class="num">01</span>
+ <div>
+ <strong>Live Dashboard Integration</strong>
+ <p>Replace the static NEXUS v0.3.1 dashboard with a dynamic view wired to <code>get_status</code>,
+ <code>agent-status</code>, and <code>predictor-status</code>. Surface real-time module health,
+ agent activity, memory pressure, and LLM token usage.</p>
+ </div>
+ </li>
+ <li>
+ <span class="num">02</span>
+ <div>
+ <strong>Agent Swarm Activation</strong>
+ <p>Convert idle agents into background workers. Assign the auto-learner to weekly skill audits,
+ the Kernel Architect to semantic dependency indexing, and searchers to stale-data refresh tasks.
+ Expand capabilities beyond read-only; grant write access under lease contracts.</p>
+ </div>
+ </li>
+ <li>
+ <span class="num">03</span>
+ <div>
+ <strong>Smart Context Auto-Routing</strong>
+ <p>Enhance the SmartContextModule to detect task intent (e.g., β€œdebug …”, β€œresearch …”, β€œcode …”)
+ and auto-switch profiles before the first tool call. This reduces token waste and improves
+ response coherence.</p>
+ </div>
+ </li>
+ <li>
+ <span class="num">04</span>
+ <div>
+ <strong>Cron-Based Maintenance</strong>
+ <p>Schedule weekly jobs via CronModule: (a) NVFS reindex, (b) log rotation,
+ (c) WebDAV backup of critical paths (<code>/skills</code>, <code>/memory</code>, <code>/config</code>),
+ (d) skill hygiene report generation.</p>
+ </div>
+ </li>
+ <li>
+ <span class="num">05</span>
+ <div>
+ <strong>VFS Root Consolidation</strong>
+ <p>Move version files to <code>/docs/changelog/</code>, relocate <code>three.js</code> to
+ <code>/scripts/lib/</code>, and split <code>help.html</code> into chunked topic files under
+ <code>/docs/help/</code>. Implement debug.log rotation at 50 KB.</p>
+ </div>
+ </li>
+ <li>
+ <span class="num">06</span>
+ <div>
+ <strong>World Model & Memory Graph Surface</strong>
+ <p>Feed WorldModelModule summaries into the AI assistant’s system prompt for recursive
+ self-awareness. Expose MemoryGraphModule as an interactive 3D force-directed visualization
+ (reusing the ThreeModule pipeline).</p>
+ </div>
+ </li>
+ <li>
+ <span class="num">07</span>
+ <div>
+ <strong>Predictive Preloading</strong>
+ <p>Use PredictorModule telemetry to pre-load likely modules and context profiles based on
+ time-of-day patterns (e.g., research mode in mornings, coding in afternoons), reducing
+ latency on first command.</p>
+ </div>
+ </li>
+ <li>
+ <span class="num">08</span>
+ <div>
+ <strong>Skill Deduplication & Tagging</strong>
+ <p>Merge overlapping mindmap skills, populate empty descriptions, and enforce mandatory
+ tags/categories on new skill creation. Add a <code>skill-audit</code> command to the
+ SkillPackCoreModule.</p>
+ </div>
+ </li>
+ <li>
+ <span class="num">09</span>
+ <div>
+ <strong>Floating Health Alerts</strong>
+ <p>Leverage FloatingModule to display non-intrusive banners when: agent failures spike,
+ VFS free space drops, Ollama proxy latency exceeds threshold, or a module fails to load.</p>
+ </div>
+ </li>
+ <li>
+ <span class="num">10</span>
+ <div>
+ <strong>Session Analytics Export</strong>
+ <p>Aggregate <code>session_stats</code> and <code>get_usage_stats</code> into a weekly
+ JSON report stored in <code>/exports/telemetry/</code>. Track trends in token consumption,
+ average latency, and task-completion rates.</p>
+ </div>
+ </li>
+ </ul>
+ </section>
+
+ <!-- Implementation Roadmap -->
+ <section>
+ <h2><span class="badge">Roadmap</span> Suggested Implementation Order</h2>
+ <table>
+ <tr><th>Phase</th><th>Week</th><th>Focus</th><th>Expected Impact</th></tr>
+ <tr>
+ <td>1</td>
+ <td>1</td>
+ <td>VFS cleanup + Skill audit + Cron scheduler setup</td>
+ <td>Reduced clutter; cleaner KB; automated maintenance baseline.</td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>2</td>
+ <td>Dashboard wiring + Floating alerts + Health telemetry</td>
+ <td>Real-time visibility; faster incident detection.</td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td>3</td>
+ <td>Agent capability expansion + Auto-delegation rules</td>
+ <td>Background task automation; reduced manual overhead.</td>
+ </tr>
+ <tr>
+ <td>4</td>
+ <td>4</td>
+ <td>World Model prompt injection + Memory Graph 3D viz</td>
+ <td>AI self-awareness; spatial knowledge navigation.</td>
+ </tr>
+ <tr>
+ <td>5</td>
+ <td>5</td>
+ <td>Predictive preloader + Session analytics pipeline</td>
+ <td>Sub-second context switching; data-driven optimization.</td>
+ </tr>
+ </table>
+ </section>
+
+ <!-- Quick Wins -->
+ <section class="info">
+ <h2><span class="badge info">Quick Wins</span> Zero-Cost Improvements (Do Today)</h2>
+ <ul>
+ <li>Run <code>nvfs-index</code> to refresh the semantic VFS index.</li>
+ <li>Move <code>v4.5.80</code>, <code>v4.5.81</code>, <code>v4.5.82</code> into <code>/archive/versions/</code>.</li>
+ <li>Delete or rotate <code>debug.log</code> if older than 30 days.</li>
+ <li>Assign the auto-learner agent a recurring task to audit skills.</li>
+ <li>Switch SmartContext profile automatically at session start based on last-used context.</li>
+ </ul>
+ </section>
+
+</div>
+
+<footer>
+ WebX11 newOS4 System Analysis &bull; Generated by AI Assistant Module &bull; 2026-07-03
+</footer>
+
+</body>
+</html> \ No newline at end of file
diff --git a/downloads/system-review-v4.6.00.html b/downloads/system-review-v4.6.00.html
new file mode 100644
index 0000000..907944b
--- /dev/null
+++ b/downloads/system-review-v4.6.00.html
@@ -0,0 +1,603 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>newOS4 v4.6.00 β€” System Review</title>
+<style>
+:root {
+ --bg: #0a0e14;
+ --bg-card: #0f141c;
+ --bg-elev: #141a23;
+ --border: #1e2530;
+ --border-bright: #2a3340;
+ --fg: #c5cdd9;
+ --fg-dim: #6b7785;
+ --fg-bright: #e6edf3;
+ --accent: #00d9ff;
+ --accent-dim: #00d9ff33;
+ --green: #3fb950;
+ --yellow: #d29922;
+ --red: #f85149;
+ --orange: #f0883e;
+ --purple: #bc8cff;
+ --pink: #ff7b72;
+ --code-bg: #05080c;
+ --shadow: 0 4px 24px rgba(0,0,0,0.4);
+}
+* { box-sizing: border-box; margin: 0; padding: 0; }
+html, body {
+ background: var(--bg);
+ color: var(--fg);
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
+ font-size: 14px;
+ line-height: 1.6;
+ min-height: 100vh;
+}
+body {
+ background-image:
+ radial-gradient(at 20% 0%, #00d9ff08 0px, transparent 50%),
+ radial-gradient(at 80% 100%, #bc8cff08 0px, transparent 50%);
+ background-attachment: fixed;
+}
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 24px;
+}
+header {
+ background: linear-gradient(135deg, var(--bg-card) 0%, var(--bg-elev) 100%);
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 32px;
+ margin-bottom: 24px;
+ position: relative;
+ overflow: hidden;
+}
+header::before {
+ content: '';
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ height: 3px;
+ background: linear-gradient(90deg, var(--accent), var(--purple), var(--pink));
+}
+h1 {
+ font-size: 32px;
+ font-weight: 700;
+ color: var(--fg-bright);
+ margin-bottom: 8px;
+ letter-spacing: -0.5px;
+}
+.subtitle {
+ color: var(--fg-dim);
+ font-size: 16px;
+ margin-bottom: 20px;
+}
+.meta {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ align-items: center;
+}
+.badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 4px 10px;
+ border-radius: 12px;
+ font-size: 12px;
+ font-weight: 500;
+ background: var(--bg);
+ border: 1px solid var(--border);
+}
+.badge.green { color: var(--green); border-color: var(--green); background: #3fb95011; }
+.badge.accent { color: var(--accent); border-color: var(--accent); background: var(--accent-dim); }
+.badge.yellow { color: var(--yellow); border-color: var(--yellow); background: #d2992211; }
+.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
+.section {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 24px;
+ margin-bottom: 20px;
+ box-shadow: var(--shadow);
+}
+h2 {
+ font-size: 20px;
+ color: var(--fg-bright);
+ margin-bottom: 16px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid var(--border);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+h2::before {
+ content: '';
+ width: 3px;
+ height: 18px;
+ background: var(--accent);
+ border-radius: 2px;
+}
+h3 {
+ font-size: 16px;
+ color: var(--fg-bright);
+ margin: 20px 0 10px;
+ font-weight: 600;
+}
+.summary-box {
+ background: linear-gradient(135deg, var(--bg-elev), var(--bg-card));
+ border-left: 3px solid var(--accent);
+ padding: 16px 20px;
+ border-radius: 6px;
+ margin-bottom: 16px;
+}
+.summary-box p { color: var(--fg-bright); font-size: 15px; }
+.metrics {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
+ gap: 12px;
+ margin-top: 12px;
+}
+.metric {
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 14px 16px;
+}
+.metric-label { font-size: 11px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
+.metric-value { font-size: 24px; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
+.metric-value.green { color: var(--green); }
+.metric-value.purple { color: var(--purple); }
+.metric-value.yellow { color: var(--yellow); }
+.metric-value.pink { color: var(--pink); }
+table {
+ width: 100%;
+ border-collapse: collapse;
+ margin-top: 12px;
+ font-size: 13px;
+}
+th, td {
+ text-align: left;
+ padding: 10px 12px;
+ border-bottom: 1px solid var(--border);
+}
+th {
+ font-weight: 600;
+ color: var(--fg-dim);
+ text-transform: uppercase;
+ font-size: 11px;
+ letter-spacing: 0.5px;
+ background: var(--bg-elev);
+}
+tr:hover td { background: var(--bg-elev); }
+code, pre {
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Courier New', monospace;
+ font-size: 13px;
+}
+code {
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 4px;
+ padding: 2px 6px;
+ color: var(--accent);
+}
+pre {
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+ overflow-x: auto;
+ margin: 12px 0;
+ line-height: 1.5;
+ color: var(--fg);
+}
+pre .comment { color: var(--fg-dim); }
+pre .keyword { color: var(--purple); }
+pre .string { color: var(--green); }
+pre .func { color: var(--accent); }
+.loop-diagram {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ gap: 8px;
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+ margin: 12px 0;
+ font-family: 'SF Mono', monospace;
+ font-size: 12px;
+}
+.loop-step {
+ background: var(--bg-elev);
+ border: 1px solid var(--border-bright);
+ border-radius: 4px;
+ padding: 6px 10px;
+ color: var(--fg-bright);
+ white-space: nowrap;
+}
+.loop-arrow { color: var(--accent); font-weight: bold; }
+.callout {
+ border-left: 3px solid;
+ padding: 12px 16px;
+ border-radius: 4px;
+ margin: 12px 0;
+ background: var(--bg-elev);
+}
+.callout.warn { border-color: var(--yellow); }
+.callout.info { border-color: var(--accent); }
+.callout.success { border-color: var(--green); }
+.callout.danger { border-color: var(--red); }
+.callout strong { color: var(--fg-bright); }
+.grid-2 {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 16px;
+ margin-top: 12px;
+}
+.card {
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+}
+.card-title { font-size: 13px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }
+ul { list-style: none; padding: 0; }
+ul li {
+ padding: 4px 0 4px 18px;
+ position: relative;
+ color: var(--fg);
+}
+ul li::before {
+ content: 'β–Έ';
+ position: absolute;
+ left: 0;
+ color: var(--accent);
+}
+.module-name { font-family: monospace; color: var(--accent); }
+.tag {
+ display: inline-block;
+ padding: 1px 6px;
+ border-radius: 3px;
+ font-size: 11px;
+ font-weight: 500;
+ margin-left: 6px;
+}
+.tag.core { background: #00d9ff22; color: var(--accent); }
+.tag.ext { background: #bc8cff22; color: var(--purple); }
+.footer {
+ text-align: center;
+ color: var(--fg-dim);
+ font-size: 12px;
+ margin-top: 32px;
+ padding-top: 20px;
+ border-top: 1px solid var(--border);
+}
+.progress {
+ height: 6px;
+ background: var(--bg);
+ border-radius: 3px;
+ overflow: hidden;
+ margin-top: 4px;
+}
+.progress-bar {
+ height: 100%;
+ background: linear-gradient(90deg, var(--accent), var(--green));
+ border-radius: 3px;
+}
+@media (max-width: 640px) {
+ .container { padding: 12px; }
+ header { padding: 20px; }
+ h1 { font-size: 24px; }
+ .section { padding: 16px; }
+ .loop-diagram { flex-direction: column; align-items: stretch; }
+ .loop-arrow { transform: rotate(90deg); align-self: center; }
+}
+</style>
+</head>
+<body>
+<div class="container">
+
+<header>
+ <h1>newOS4 <span style="color: var(--accent);">v4.6.00</span></h1>
+ <p class="subtitle">System Architecture Review β€” Self-Improving Module Loop</p>
+ <div class="meta">
+ <span class="badge green"><span class="dot"></span>Healthy</span>
+ <span class="badge accent"><span class="dot"></span>v4.6.00</span>
+ <span class="badge"><span class="dot"></span>43 modules</span>
+ <span class="badge"><span class="dot"></span>14 skills</span>
+ <span class="badge"><span class="dot"></span>145 files</span>
+ <span class="badge yellow"><span class="dot"></span>3 agents stale</span>
+ </div>
+</header>
+
+<!-- Executive Summary -->
+<section class="section">
+ <h2>Executive Summary</h2>
+ <div class="summary-box">
+ <p><strong>Shipped:</strong> A self-improving module pipeline that lets the AI edit, test, and validate its own modules in dry-run mode without human intervention. The <code>ship_module</code> tool orchestrates test β†’ health check β†’ regression suite, with auto-rollback at every stage. Server persistence (commit) is intentionally gated behind human approval.</p>
+ </div>
+ <div class="metrics">
+ <div class="metric">
+ <div class="metric-label">Modules</div>
+ <div class="metric-value">43</div>
+ <div class="progress"><div class="progress-bar" style="width: 100%"></div></div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Core / Ext</div>
+ <div class="metric-value green">21 / 22</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Files in VFS</div>
+ <div class="metric-value purple">145</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Skills</div>
+ <div class="metric-value yellow">14</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">AI Profiles</div>
+ <div class="metric-value">11</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Agent Loops</div>
+ <div class="metric-value pink">7</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Memory Nodes</div>
+ <div class="metric-value">19</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Heap Used</div>
+ <div class="metric-value yellow">256MB</div>
+ </div>
+ </div>
+</section>
+
+<!-- v4.6.00 The Loop -->
+<section class="section">
+ <h2>v4.6.00 β€” The Self-Improvement Loop</h2>
+
+ <div class="callout info">
+ <strong>Goal:</strong> AI detects a bug or missing feature, calls <code>ship_module({name, code, tests, commit:false})</code>, and the system writes the change, runs the test, runs the health check, runs the regression suite β€” and either reports "dry-run passed" or auto-rolls back with a failure report. No human needed for the dry-run path.
+ </div>
+
+ <div class="loop-diagram">
+ <span class="loop-step">AI detects bug</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">ship_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">test_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">health_check</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">regression</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">βœ“ / rollback</span>
+ </div>
+
+ <h3>Phase Breakdown</h3>
+ <table>
+ <thead>
+ <tr><th>Phase</th><th>Tool</th><th>What</th><th>Verified</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><strong>A</strong></td>
+ <td><code>test_module</code> (rewritten)</td>
+ <td>Loads module, checks JS errors, verifies commands registered, runs test assertions, auto-rollback on any failure</td>
+ <td>βœ… Assertions catch mismatches, rollback restores old instance</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td><code>health_check</code> (new)</td>
+ <td>Runs core commands (ls, pwd, echo, help), checks world model version, agent health, module count</td>
+ <td>βœ… Returns {healthy, coreCommands, agents, versionMatch}</td>
+ </tr>
+ <tr>
+ <td><strong>C</strong></td>
+ <td><code>diff_module</code> (new)</td>
+ <td>Line-by-line diff between original and edited module source in <code>_mods/</code></td>
+ <td>βœ… Shows added/removed/changed lines with line numbers</td>
+ </tr>
+ <tr>
+ <td><strong>D</strong></td>
+ <td><code>commit_module</code> (skipped)</td>
+ <td>Server persistence (WebDAV upload, bundle rebuild, version bump, rate limiting) β€” <em>intentionally deferred</em></td>
+ <td>⏸ Needs more design β€” gated behind human approval in <code>ship_module</code></td>
+ </tr>
+ <tr>
+ <td><strong>E</strong></td>
+ <td><code>_runRegressionSuite</code> (new)</td>
+ <td>Module-specific regression tests: ShellModule (export, redirect, chain, pipe), SystemModule (ls, pwd), OrchestratorModule (agents), AI tools</td>
+ <td>βœ… 4 tests for ShellModule, 3/4 passed (redirect test needs routing fix)</td>
+ </tr>
+ <tr>
+ <td><strong>F</strong></td>
+ <td><code>ship_module</code> (new)</td>
+ <td>Full pipeline: edit β†’ test β†’ health_check β†’ regression. Auto-rollback at any stage. <code>commit:true</code> = human approval needed</td>
+ <td>βœ… Pipeline aborts on test failure, reports step where it failed</td>
+ </tr>
+ </tbody>
+ </table>
+</section>
+
+<!-- Known Limitation -->
+<section class="section">
+ <h2>Known Limitation & Next Fix</h2>
+ <div class="callout warn">
+ <strong>Issue:</strong> Regression tests use <code>_captureCommandOutput</code> which calls <code>security.checkAndRun()</code> β€” this routes to the first module that has the command, bypassing the shell parser. Tests for shell-specific features (redirect, pipe) need to go through <code>executeCommand</code> instead.
+ <br><br>
+ <strong>Classification:</strong> Test design issue, not a framework bug.
+ <br><br>
+ <strong>Fix plan:</strong> Add a second test path <code>_captureShellCommand</code> that routes through the real shell parser for redirect/pipe/export cases. Keep <code>_captureCommandOutput</code> as the generic helper. β†’ target v4.6.01
+ </div>
+</section>
+
+<!-- Files Modified -->
+<section class="section">
+ <h2>Files Modified</h2>
+ <ul>
+ <li><span class="module-name">module-aiassist.js</span> <span class="tag core">core</span> β€” 4 new tool definitions, test_module rewrite, 3 new handlers, <code>_captureCommandOutput</code> + <code>_runRegressionSuite</code> helpers</li>
+ <li><span class="module-name">core-bundle.js</span> <span class="tag core">core</span> β€” same changes synced to bundled core</li>
+ <li><span class="module-name">main.html</span> <span class="tag core">core</span> β€” version bump β†’ v4.6.00</li>
+ </ul>
+</section>
+
+<!-- Usage Stats -->
+<section class="section">
+ <h2>Usage Statistics</h2>
+ <div class="grid-2">
+ <div class="card">
+ <div class="card-title">Aggregate (last 24h)</div>
+ <ul>
+ <li><strong>Total requests:</strong> 246</li>
+ <li><strong>Prompt tokens:</strong> 4,140,000</li>
+ <li><strong>Completion tokens:</strong> 318,000</li>
+ <li><strong>Avg latency:</strong> 20.3s</li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">By Model (top)</div>
+ <ul>
+ <li><code>MiniMax-M3</code> β€” 168 reqs, 2.8M prompt, 18.2s avg</li>
+ <li><code>MiniMax-Coder</code> β€” 78 reqs, 1.3M prompt, 23.1s avg</li>
+ </ul>
+ </div>
+ </div>
+</section>
+
+<!-- Module Breakdown -->
+<section class="section">
+ <h2>Module Breakdown</h2>
+ <table>
+ <thead>
+ <tr><th>Core Modules</th><th>Layer</th><th>Status</th></tr>
+ </thead>
+ <tbody>
+ <tr><td>SystemModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>ShellModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>FSModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>AIModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>OrchestratorModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>ModuleManagerModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>SecurityModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>UIModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>WebDAVModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>WorldModelModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>SkillModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>AgentModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>... + 9 more</td><td>β€”</td><td>βœ… loaded</td></tr>
+ </tbody>
+ </table>
+ <p style="margin-top: 12px; color: var(--fg-dim); font-size: 13px;">22 external modules also loaded (vaultmind, hyperliquid, sandbox, worldmodel, etc.)</p>
+</section>
+
+<!-- Agents -->
+<section class="section">
+ <h2>Agents</h2>
+ <div class="grid-2">
+ <div class="card">
+ <div class="card-title">Active (3)</div>
+ <ul>
+ <li><code>research-agent</code> β€” 12 tasks done</li>
+ <li><code>code-agent</code> β€” 5 tasks done</li>
+ <li><code>writer-agent</code> β€” 8 tasks done</li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">Stale (3) ⚠️</div>
+ <ul>
+ <li><code>old-researcher</code> β€” last seen 14d ago</li>
+ <li><code>legacy-coder</code> β€” last seen 21d ago</li>
+ <li><code>test-runner-1</code> β€” last seen 9d ago</li>
+ </ul>
+ </div>
+ </div>
+</section>
+
+<!-- Skills -->
+<section class="section">
+ <h2>Skills (14)</h2>
+ <div class="grid-2">
+ <div class="card">
+ <div class="card-title">Research / System</div>
+ <ul>
+ <li>web-research</li>
+ <li>self-improving-loop</li>
+ <li>module-test-patterns</li>
+ <li>world-model-queries</li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">Dev / Security</div>
+ <ul>
+ <li>module-editing</li>
+ <li>shell-scripting</li>
+ <li>vault-patterns</li>
+ <li>guardrail-usage</li>
+ <li>... + 6 more</li>
+ </ul>
+ </div>
+ </div>
+</section>
+
+<!-- VFS Layout -->
+<section class="section">
+ <h2>VFS Layout</h2>
+ <pre><code>/
+β”œβ”€β”€ <span class="string">agents/</span> <span class="comment"># agent configs</span>
+β”œβ”€β”€ <span class="string">core/</span> <span class="comment"># core modules source</span>
+β”œβ”€β”€ <span class="string">ext/</span> <span class="comment"># external modules</span>
+β”œβ”€β”€ <span class="string">mods/</span> <span class="comment"># local edits (_mods/ + auto-test)</span>
+β”œβ”€β”€ <span class="string">skills/</span> <span class="comment"># 14 skill markdown files</span>
+β”œβ”€β”€ <span class="string">sessions/</span> <span class="comment"># session summaries</span>
+β”œβ”€β”€ <span class="string">system/</span> <span class="comment"># system docs (this file)</span>
+β”œβ”€β”€ <span class="string">uploads/</span> <span class="comment"># user uploads</span>
+β”œβ”€β”€ <span class="string">user/</span> <span class="comment"># user profile</span>
+β”œβ”€β”€ <span class="string">vaultmind/</span> <span class="comment"># AI query cache</span>
+└── <span class="string">webdav/</span> <span class="comment"># WebDAV mounts</span></code></pre>
+</section>
+
+<!-- AI Profiles -->
+<section class="section">
+ <h2>AI Context Profiles</h2>
+ <table>
+ <thead>
+ <tr><th>Profile</th><th>Domain</th><th>Use Case</th></tr>
+ </thead>
+ <tbody>
+ <tr><td><code>coding</code></td><td>code editing</td><td>module dev, refactor</td></tr>
+ <tr><td><code>debug</code></td><td>bug fixing</td><td>test failures, errors</td></tr>
+ <tr><td><code>creative</code></td><td>brainstorming</td><td>design, naming</td></tr>
+ <tr><td><code>technical</code></td><td>documentation</td><td>docs, specs</td></tr>
+ <tr><td><code>chat</code></td><td>casual</td><td>general talk</td></tr>
+ <tr><td><code>system-admin</code></td><td>maintenance</td><td>health, cleanup</td></tr>
+ <tr><td><code>research</code></td><td>info gathering</td><td>web search, analysis</td></tr>
+ <tr><td><code>security</code></td><td>threat assessment</td><td>guardrail, audit</td></tr>
+ <tr><td>... +3 more</td><td>β€”</td><td>β€”</td></tr>
+ </tbody>
+ </table>
+</section>
+
+<!-- Recommendations -->
+<section class="section">
+ <h2>Recommendations (Next Iterations)</h2>
+ <ol style="padding-left: 20px;">
+ <li><strong>v4.6.01</strong> β€” Fix redirect/pipe regression test (add <code>_captureShellCommand</code> path)</li>
+ <li><strong>v4.6.02</strong> β€” Clean up 3 stale agents</li>
+ <li><strong>v4.7.00</strong> β€” Phase D: <code>commit_module</code> with proper WebDAV upload, bundle rebuild, version bump, rate limiting</li>
+ <li><strong>v4.7.x</strong> β€” Expand regression suite to cover all 21 core modules</li>
+ <li><strong>v4.8.x</strong> β€” Add a "watchdog" agent that auto-detects bugs in the loop itself</li>
+ </ol>
+</section>
+
+<div class="footer">
+ Generated by newOS4 v4.6.00 Β· Self-Improving Loop Β· <span style="color: var(--accent);">2026-07-06 02:13 AM</span>
+</div>
+
+</div>
+</body>
+</html>
diff --git a/downloads/system-review-v4.6.02.html b/downloads/system-review-v4.6.02.html
new file mode 100644
index 0000000..be84aef
--- /dev/null
+++ b/downloads/system-review-v4.6.02.html
@@ -0,0 +1,767 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>newOS4 v4.6.02 β€” System Review</title>
+<style>
+:root {
+ --bg: #0a0e14;
+ --bg-card: #0f141c;
+ --bg-elev: #141a23;
+ --border: #1e2530;
+ --border-bright: #2a3340;
+ --fg: #c5cdd9;
+ --fg-dim: #6b7785;
+ --fg-bright: #e6edf3;
+ --accent: #00d9ff;
+ --accent-dim: #00d9ff33;
+ --green: #3fb950;
+ --yellow: #d29922;
+ --red: #f85149;
+ --orange: #f0883e;
+ --purple: #bc8cff;
+ --pink: #ff7b72;
+ --code-bg: #05080c;
+ --shadow: 0 4px 24px rgba(0,0,0,0.4);
+}
+* { box-sizing: border-box; margin: 0; padding: 0; }
+html, body {
+ background: var(--bg);
+ color: var(--fg);
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
+ font-size: 14px;
+ line-height: 1.6;
+ min-height: 100vh;
+}
+body {
+ background-image:
+ radial-gradient(at 20% 0%, #00d9ff08 0px, transparent 50%),
+ radial-gradient(at 80% 100%, #bc8cff08 0px, transparent 50%);
+ background-attachment: fixed;
+}
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 24px;
+}
+header {
+ background: linear-gradient(135deg, var(--bg-card) 0%, var(--bg-elev) 100%);
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 32px;
+ margin-bottom: 24px;
+ position: relative;
+ overflow: hidden;
+}
+header::before {
+ content: '';
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ height: 3px;
+ background: linear-gradient(90deg, var(--accent), var(--purple), var(--pink));
+}
+h1 {
+ font-size: 32px;
+ font-weight: 700;
+ color: var(--fg-bright);
+ margin-bottom: 8px;
+ letter-spacing: -0.5px;
+}
+.subtitle {
+ color: var(--fg-dim);
+ font-size: 16px;
+ margin-bottom: 20px;
+}
+.meta {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ align-items: center;
+}
+.badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 4px 10px;
+ border-radius: 12px;
+ font-size: 12px;
+ font-weight: 500;
+ background: var(--bg);
+ border: 1px solid var(--border);
+}
+.badge.green { color: var(--green); border-color: var(--green); background: #3fb95011; }
+.badge.accent { color: var(--accent); border-color: var(--accent); background: var(--accent-dim); }
+.badge.yellow { color: var(--yellow); border-color: var(--yellow); background: #d2992211; }
+.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
+.section {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 24px;
+ margin-bottom: 20px;
+ box-shadow: var(--shadow);
+}
+h2 {
+ font-size: 20px;
+ color: var(--fg-bright);
+ margin-bottom: 16px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid var(--border);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+h2::before {
+ content: '';
+ width: 3px;
+ height: 18px;
+ background: var(--accent);
+ border-radius: 2px;
+}
+h3 {
+ font-size: 16px;
+ color: var(--fg-bright);
+ margin: 20px 0 10px;
+ font-weight: 600;
+}
+.summary-box {
+ background: linear-gradient(135deg, var(--bg-elev), var(--bg-card));
+ border-left: 3px solid var(--accent);
+ padding: 16px 20px;
+ border-radius: 6px;
+ margin-bottom: 16px;
+}
+.summary-box p { color: var(--fg-bright); font-size: 15px; }
+.metrics {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
+ gap: 12px;
+ margin-top: 12px;
+}
+.metric {
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 14px 16px;
+}
+.metric-label { font-size: 11px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
+.metric-value { font-size: 24px; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
+.metric-value.green { color: var(--green); }
+.metric-value.purple { color: var(--purple); }
+.metric-value.yellow { color: var(--yellow); }
+.metric-value.pink { color: var(--pink); }
+table {
+ width: 100%;
+ border-collapse: collapse;
+ margin-top: 12px;
+ font-size: 13px;
+}
+th, td {
+ text-align: left;
+ padding: 10px 12px;
+ border-bottom: 1px solid var(--border);
+}
+th {
+ font-weight: 600;
+ color: var(--fg-dim);
+ text-transform: uppercase;
+ font-size: 11px;
+ letter-spacing: 0.5px;
+ background: var(--bg-elev);
+}
+tr:hover td { background: var(--bg-elev); }
+code, pre {
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Courier New', monospace;
+ font-size: 13px;
+}
+code {
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 4px;
+ padding: 2px 6px;
+ color: var(--accent);
+}
+pre {
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+ overflow-x: auto;
+ margin: 12px 0;
+ line-height: 1.5;
+ color: var(--fg);
+}
+pre .comment { color: var(--fg-dim); }
+pre .keyword { color: var(--purple); }
+pre .string { color: var(--green); }
+pre .func { color: var(--accent); }
+.loop-diagram {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ gap: 8px;
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+ margin: 12px 0;
+ font-family: 'SF Mono', monospace;
+ font-size: 12px;
+}
+.loop-step {
+ background: var(--bg-elev);
+ border: 1px solid var(--border-bright);
+ border-radius: 4px;
+ padding: 6px 10px;
+ color: var(--fg-bright);
+ white-space: nowrap;
+}
+.loop-arrow { color: var(--accent); font-weight: bold; }
+.callout {
+ border-left: 3px solid;
+ padding: 12px 16px;
+ border-radius: 4px;
+ margin: 12px 0;
+ background: var(--bg-elev);
+}
+.callout.warn { border-color: var(--yellow); }
+.callout.info { border-color: var(--accent); }
+.callout.success { border-color: var(--green); }
+.callout.danger { border-color: var(--red); }
+.callout strong { color: var(--fg-bright); }
+.grid-2 {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 16px;
+ margin-top: 12px;
+}
+.card {
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+}
+.card-title { font-size: 13px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }
+ul { list-style: none; padding: 0; }
+ul li {
+ padding: 4px 0 4px 18px;
+ position: relative;
+ color: var(--fg);
+}
+ul li::before {
+ content: 'β–Έ';
+ position: absolute;
+ left: 0;
+ color: var(--accent);
+}
+.module-name { font-family: monospace; color: var(--accent); }
+.tag {
+ display: inline-block;
+ padding: 1px 6px;
+ border-radius: 3px;
+ font-size: 11px;
+ font-weight: 500;
+ margin-left: 6px;
+}
+.tag.core { background: #00d9ff22; color: var(--accent); }
+.tag.ext { background: #bc8cff22; color: var(--purple); }
+.footer {
+ text-align: center;
+ color: var(--fg-dim);
+ font-size: 12px;
+ margin-top: 32px;
+ padding-top: 20px;
+ border-top: 1px solid var(--border);
+}
+.progress {
+ height: 6px;
+ background: var(--bg);
+ border-radius: 3px;
+ overflow: hidden;
+ margin-top: 4px;
+}
+.progress-bar {
+ height: 100%;
+ background: linear-gradient(90deg, var(--accent), var(--green));
+ border-radius: 3px;
+}
+.version-trail {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-wrap: wrap;
+ font-family: monospace;
+ font-size: 13px;
+ margin: 12px 0;
+}
+.vt-version {
+ padding: 4px 10px;
+ border-radius: 4px;
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+}
+.vt-version.current { color: var(--green); border-color: var(--green); background: #3fb95011; }
+.vt-version.past { color: var(--fg-dim); }
+.vt-arrow { color: var(--accent); }
+.two-step {
+ display: grid;
+ grid-template-columns: 1fr auto 1fr;
+ gap: 16px;
+ align-items: center;
+ margin: 16px 0;
+}
+.two-step-step {
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+}
+.two-step-step.ai { border-left: 3px solid var(--purple); }
+.two-step-step.human { border-left: 3px solid var(--green); }
+.two-step-step h4 {
+ font-size: 13px;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ margin-bottom: 8px;
+}
+.two-step-step.ai h4 { color: var(--purple); }
+.two-step-step.human h4 { color: var(--green); }
+.two-step-divider {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+ color: var(--accent);
+ font-size: 18px;
+}
+.two-step-divider span { font-size: 10px; color: var(--fg-dim); text-transform: uppercase; }
+@media (max-width: 768px) {
+ .two-step { grid-template-columns: 1fr; }
+ .two-step-divider { transform: rotate(90deg); padding: 8px 0; }
+}
+@media (max-width: 640px) {
+ .container { padding: 12px; }
+ header { padding: 20px; }
+ h1 { font-size: 24px; }
+ .section { padding: 16px; }
+ .loop-diagram { flex-direction: column; align-items: stretch; }
+ .loop-arrow { transform: rotate(90deg); align-self: center; }
+}
+</style>
+</head>
+<body>
+<div class="container">
+
+<header>
+ <h1>newOS4 <span style="color: var(--accent);">v4.6.02</span></h1>
+ <p class="subtitle">System Architecture Review β€” Phase D: Self-Improvement Loop Closed</p>
+ <div class="meta">
+ <span class="badge green"><span class="dot"></span>Healthy</span>
+ <span class="badge accent"><span class="dot"></span>v4.6.02</span>
+ <span class="badge"><span class="dot"></span>43 modules</span>
+ <span class="badge"><span class="dot"></span>14 skills</span>
+ <span class="badge"><span class="dot"></span>177 files</span>
+ <span class="badge green"><span class="dot"></span>Phase D Complete</span>
+ </div>
+</header>
+
+<!-- Version Trail -->
+<section class="section">
+ <h2>Version Trail</h2>
+ <div class="version-trail">
+ <span class="vt-version past">v4.6.00</span>
+ <span class="vt-arrow">β†’</span>
+ <span class="vt-version past">v4.6.01</span>
+ <span class="vt-arrow">β†’</span>
+ <span class="vt-version current">v4.6.02</span>
+ <span style="color: var(--fg-dim); font-size: 12px; margin-left: 12px;">Migrated to simplified vX.Y.ZZ scheme (no date prefix). Backward-compatible regex in main.html.</span>
+ </div>
+</section>
+
+<!-- Executive Summary -->
+<section class="section">
+ <h2>Executive Summary</h2>
+ <div class="summary-box">
+ <p><strong>Shipped:</strong> The self-improvement loop is <strong>fully closed</strong>. The AI can now autonomously edit, test, verify, and persist module changes to the server β€” with a <strong>human approval gate</strong> as the final step. The two-step handshake (AI proposes β†’ human approves) ensures no server write happens without explicit human consent.</p>
+ </div>
+ <div class="metrics">
+ <div class="metric">
+ <div class="metric-label">Modules</div>
+ <div class="metric-value">43</div>
+ <div class="progress"><div class="progress-bar" style="width: 100%"></div></div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Core / Ext</div>
+ <div class="metric-value green">21 / 22</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Files in VFS</div>
+ <div class="metric-value purple">177</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Skills</div>
+ <div class="metric-value yellow">14</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">AI Profiles</div>
+ <div class="metric-value">11</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Agent Loops</div>
+ <div class="metric-value pink">7</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Memory Nodes</div>
+ <div class="metric-value">13</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Commits Today</div>
+ <div class="metric-value green">1 / 5</div>
+ </div>
+ </div>
+</section>
+
+<!-- Phase D β€” The Full Loop -->
+<section class="section">
+ <h2>v4.6.02 β€” Phase D: The Full Loop</h2>
+
+ <div class="callout success">
+ <strong>Milestone:</strong> The AI can now propose, test, and request a server commit. A human types <code>commit-approve [comment]</code> to push it. The two-step handshake is the kill switch β€” no autonomous server writes.
+ </div>
+
+ <div class="loop-diagram">
+ <span class="loop-step">AI detects bug</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">edit_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">test_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">health_check</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">regression</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">ship_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">commit_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step" style="color: var(--green); border-color: var(--green);">commit-approve</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step" style="color: var(--green);">WebDAV PUT βœ“</span>
+ </div>
+
+ <h3>Two-Step Handshake</h3>
+ <div class="two-step">
+ <div class="two-step-step ai">
+ <h4>AI Side (autonomous)</h4>
+ <ul>
+ <li><code>edit_module({name, code})</code> β†’ writes to VFS <code>_mods/</code></li>
+ <li><code>test_module({name, tests})</code> β†’ assertions + auto-rollback</li>
+ <li><code>health_check()</code> β†’ core cmds + world model + agents</li>
+ <li><code>_runRegressionSuite()</code> β†’ 4/4 ShellModule tests</li>
+ <li><code>ship_module({name, code, tests})</code> β†’ full dry-run pipeline</li>
+ <li><code>commit_module({name, file})</code> β†’ creates <em>pending</em> commit with diff</li>
+ </ul>
+ </div>
+ <div class="two-step-divider">
+ <span>handoff</span>
+ <span>⟷</span>
+ <span>approval</span>
+ </div>
+ <div class="two-step-step human">
+ <h4>Human Side (gate)</h4>
+ <ul>
+ <li><code>commit-approve [comment]</code> β†’ WebDAV push + version bump</li>
+ <li><code>commit-deny [reason]</code> β†’ clears pending commit</li>
+ <li><code>commit-status</code> β†’ view pending diff + rate limit</li>
+ </ul>
+ </div>
+ </div>
+
+ <h3>Phase Breakdown</h3>
+ <table>
+ <thead>
+ <tr><th>Phase</th><th>Tool</th><th>What</th><th>Status</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><strong>A</strong></td>
+ <td><code>test_module</code></td>
+ <td>Loads module, checks JS errors, verifies commands, runs assertions, auto-rollback on failure</td>
+ <td>βœ… Shipped v4.6.00</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td><code>health_check</code></td>
+ <td>Core commands, world model version, agent health, module count</td>
+ <td>βœ… Shipped v4.6.00</td>
+ </tr>
+ <tr>
+ <td><strong>C</strong></td>
+ <td><code>diff_module</code></td>
+ <td>Line-by-line diff between original and edited module source</td>
+ <td>βœ… Shipped v4.6.00</td>
+ </tr>
+ <tr>
+ <td><strong>D</strong></td>
+ <td><code>commit_module</code></td>
+ <td>Creates pending commit: WebDAV upload, version bump, rate limiting β€” <strong>gated by human approval</strong></td>
+ <td>βœ… <strong>Shipped v4.6.02</strong></td>
+ </tr>
+ <tr>
+ <td><strong>E</strong></td>
+ <td><code>_runRegressionSuite</code></td>
+ <td>Module-specific regression: ShellModule (export, redirect, chain, pipe)</td>
+ <td>βœ… 4/4 (v4.6.01 routing fix verified)</td>
+ </tr>
+ <tr>
+ <td><strong>F</strong></td>
+ <td><code>ship_module</code></td>
+ <td>Full dry-run pipeline: edit β†’ test β†’ health β†’ regression. Auto-rollback at any stage.</td>
+ <td>βœ… Shipped v4.6.00</td>
+ </tr>
+ </tbody>
+ </table>
+</section>
+
+<!-- What v4.6.02 Added -->
+<section class="section">
+ <h2>What v4.6.02 Added</h2>
+ <div class="grid-2">
+ <div class="card">
+ <div class="card-title">New Tools (AI-facing)</div>
+ <ul>
+ <li><code>health_check()</code></li>
+ <li><code>diff_module({name})</code></li>
+ <li><code>ship_module({name, code, tests, commit})</code></li>
+ <li><code>commit_module({name, file})</code></li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">New Commands (Human-facing)</div>
+ <ul>
+ <li><code>commit-approve [comment]</code></li>
+ <li><code>commit-deny [reason]</code></li>
+ <li><code>commit-status</code></li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">New Handlers (in module-aiassist.js)</div>
+ <ul>
+ <li><code>_executeCommit()</code></li>
+ <li><code>_webdavPush()</code> / <code>_webdavGet()</code></li>
+ <li><code>_syncBundle()</code></li>
+ <li><code>_bumpVersion()</code> / <code>_parseVersion()</code></li>
+ <li><code>_extractClassBlock()</code></li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">Version Scheme</div>
+ <ul>
+ <li>Old: <code>YYYY-MM-DD-vX.Y.ZZ</code></li>
+ <li>New: <code>vX.Y.ZZ</code> (SemVer-ish)</li>
+ <li>Backward-compatible regex in main.html</li>
+ <li>Optional <code>+YYYYMMDD</code> build metadata for traceability</li>
+ </ul>
+ </div>
+ </div>
+</section>
+
+<!-- Real Server Write Verification -->
+<section class="section">
+ <h2>Real Server Write β€” Verified</h2>
+ <div class="callout success">
+ <strong>End-to-end commit flow verified against live server:</strong>
+ </div>
+ <pre><code><span class="comment"># Terminal session transcript</span>
+commit-module tutorial.js
+ β†’ <span class="string">Pending commit created for modules/ext/tutorial.js</span>
+ β†’ <span class="string">Diff: 4 lines added, 1 removed</span>
+ β†’ <span class="string">Rate limit: 4/5 commits remaining</span>
+
+commit-approve Tested locally, 4/4 regression pass
+ β†’ <span class="func">_webdavPut</span> modules/ext/tutorial.js
+ β†’ <span class="string">HTTP 201 Created</span>
+ β†’ <span class="func">_bumpVersion</span> v4.6.01 β†’ v4.6.02
+ β†’ <span class="func">_bumpVersion</span> main.html + module-loader.js
+ β†’ <span class="string">_mods/ cleanup</span>
+ β†’ πŸŽ‰ <span class="string">Commit complete! Refresh to load v4.6.02</span></code></pre>
+</section>
+
+<!-- Rate Limiting & Commit Log -->
+<section class="section">
+ <h2>Rate Limiting & Audit Trail</h2>
+ <table>
+ <thead>
+ <tr><th>Constraint</th><th>Value</th><th>Enforced By</th></tr>
+ </thead>
+ <tbody>
+ <tr><td>Max commits per day</td><td>5</td><td><code>commit-log.json</code> + timestamp check</td></tr>
+ <tr><td>Cooldown between commits</td><td>10 minutes</td><td>last-commit timestamp</td></tr>
+ <tr><td>Audit log location</td><td><code>/_mods/commit-log.json</code></td><td>Appended on every approve/deny</td></tr>
+ <tr><td>Pending commit storage</td><td><code>/_mods/pending-commit.json</code></td><td>Cleared on approve/deny</td></tr>
+ </tbody>
+ </table>
+ <p style="margin-top: 12px; color: var(--yellow); font-size: 13px;">⚠ <strong>Note:</strong> Reset window for daily limit is not yet documented. See Recommendations.</p>
+</section>
+
+<!-- Bundle Sync -->
+<section class="section">
+ <h2>Bundle Sync Strategy</h2>
+ <p style="margin-bottom: 12px;">For ext modules (most cases), the server file is the source of truth. For modules bundled in <code>core-bundle.js</code> or <code>critical-ext-bundle.js</code>, <code>_syncBundle()</code> performs a <strong>block-replace</strong>:</p>
+ <ol style="padding-left: 20px; color: var(--fg);">
+ <li>Download bundle via WebDAV GET</li>
+ <li>Locate the target class by name</li>
+ <li>Find the class block boundaries via brace counting</li>
+ <li>Replace with the new class from edited code</li>
+ <li>Validate with <code>new Function()</code> (syntax check)</li>
+ <li>Upload back via WebDAV PUT</li>
+ </ol>
+ <div class="callout warn">
+ <strong>Untested in production.</strong> First real sync against <code>core-bundle.js</code> should be treated like a fresh deploy β€” back up first, verify with regression suite immediately after.
+ </div>
+</section>
+
+<!-- Files Modified -->
+<section class="section">
+ <h2>Files Modified in v4.6.02</h2>
+ <ul>
+ <li><span class="module-name">module-aiassist.js</span> <span class="tag core">core</span> β€” <code>commit_module</code> tool def + handler, <code>_executeCommit</code>, <code>_webdavPush</code>, <code>_webdavGet</code>, <code>_syncBundle</code>, <code>_bumpVersion</code>, <code>_extractClassBlock</code>, <code>_parseVersion</code>, commit-approve/commit-deny/commit-status commands</li>
+ <li><span class="module-name">core-bundle.js</span> <span class="tag core">core</span> β€” all changes synced to bundled core</li>
+ <li><span class="module-name">main.html</span> <span class="tag core">core</span> β€” version bump to v4.6.02, version regex updated for new format</li>
+ <li><span class="module-name">module-loader.js</span> <span class="tag core">core</span> β€” <code>LATEST_VER</code> updated to v4.6.02 (was stale at v4.5.94)</li>
+ </ul>
+</section>
+
+<!-- Known Limitations & Watchpoints -->
+<section class="section">
+ <h2>Known Limitations & Watchpoints</h2>
+ <table>
+ <thead>
+ <tr><th>#</th><th>Issue</th><th>Severity</th><th>Suggested Fix</th><th>Target</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>1</td>
+ <td><code>_syncBundle()</code> untested against real <code>core-bundle.js</code></td>
+ <td>🟑 Medium</td>
+ <td>Test with a no-op edit first; back up before real sync</td>
+ <td>v4.6.03</td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>Daily commit reset window not documented (midnight UTC?)</td>
+ <td>🟒 Low</td>
+ <td>Add <code>rate-limit-docs</code> skill; document in <code>commit_module</code> tool description</td>
+ <td>v4.6.03</td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td><code>commit-approve</code> has no module-name arg β€” ambiguous if 2 pending</td>
+ <td>🟒 Low</td>
+ <td>Change signature to <code>commit-approve &lt;module-name&gt; [comment]</code></td>
+ <td>v4.6.03</td>
+ </tr>
+ <tr>
+ <td>4</td>
+ <td><code>commit-log.json</code> is JSON, not append-only β€” crash mid-write could corrupt</td>
+ <td>🟑 Medium</td>
+ <td>Use write-then-rename pattern, or migrate to NDJSON</td>
+ <td>v4.6.03</td>
+ </tr>
+ <tr>
+ <td>5</td>
+ <td>3 stale agents still listed in old reviews (<code>old-researcher</code>, <code>legacy-coder</code>, <code>test-runner-1</code>)</td>
+ <td>🟒 Low</td>
+ <td>Run <code>list_agents</code> + prune; update world model</td>
+ <td>v4.6.03</td>
+ </tr>
+ </tbody>
+ </table>
+</section>
+
+<!-- Usage Stats -->
+<section class="section">
+ <h2>Usage Statistics</h2>
+ <div class="grid-2">
+ <div class="card">
+ <div class="card-title">Aggregate (last 24h)</div>
+ <ul>
+ <li><strong>Total requests:</strong> 312</li>
+ <li><strong>Prompt tokens:</strong> 5,280,000</li>
+ <li><strong>Completion tokens:</strong> 402,000</li>
+ <li><strong>Avg latency:</strong> 19.8s</li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">By Model (top)</div>
+ <ul>
+ <li><code>MiniMax-M3</code> β€” 214 reqs, 3.6M prompt, 17.4s avg</li>
+ <li><code>MiniMax-Coder</code> β€” 98 reqs, 1.6M prompt, 22.7s avg</li>
+ </ul>
+ </div>
+ </div>
+</section>
+
+<!-- VFS Layout (updated) -->
+<section class="section">
+ <h2>VFS Layout (updated)</h2>
+ <pre><code>/
+β”œβ”€β”€ <span class="string">agents/</span> <span class="comment"># agent configs</span>
+β”œβ”€β”€ <span class="string">core/</span> <span class="comment"># core modules source</span>
+β”œβ”€β”€ <span class="string">ext/</span> <span class="comment"># external modules</span>
+β”œβ”€β”€ <span class="string">_mods/</span> <span class="comment"># local edits + commit-log.json + pending-commit.json</span>
+β”œβ”€β”€ <span class="string">skills/</span> <span class="comment"># 14 skill markdown files</span>
+β”œβ”€β”€ <span class="string">sessions/</span> <span class="comment"># session summaries</span>
+β”œβ”€β”€ <span class="string">system/</span> <span class="comment"># system docs (this file)</span>
+β”œβ”€β”€ <span class="string">uploads/</span> <span class="comment"># user uploads</span>
+β”œβ”€β”€ <span class="string">user/</span> <span class="comment"># user profile</span>
+β”œβ”€β”€ <span class="string">vaultmind/</span> <span class="comment"># AI query cache</span>
+└── <span class="string">webdav/</span> <span class="comment"># WebDAV mounts</span></code></pre>
+</section>
+
+<!-- Recommendations -->
+<section class="section">
+ <h2>Recommendations (Next Iterations)</h2>
+ <ol style="padding-left: 20px;">
+ <li><strong>v4.6.03 β€” Hardening</strong>
+ <ul>
+ <li>Test <code>_syncBundle()</code> against real <code>core-bundle.js</code></li>
+ <li>Fix the 4 watchpoints above (log durability, disambiguation, docs, stale agents)</li>
+ </ul>
+ </li>
+ <li><strong>v4.7.0 β€” Phase E: Auto-test on commit</strong>
+ <ul>
+ <li>Extend <code>commit-approve</code> to optionally run regression suite as pre-flight check</li>
+ <li>Human approval never ships a broken module</li>
+ </ul>
+ </li>
+ <li><strong>v4.7.0 β€” Phase E: Conversation persistence</strong>
+ <ul>
+ <li>Save <code>session_save</code> data to WebDAV so <code>/hermes/sessions/</code> survives refresh</li>
+ <li>Currently browser-local only</li>
+ </ul>
+ </li>
+ <li><strong>v4.8.0 β€” Phase F</strong>
+ <ul>
+ <li>Module marketplace via WPM (discover, install, upgrade third-party)</li>
+ <li>Watchdog agent that auto-detects bugs in the loop itself</li>
+ </ul>
+ </li>
+ <li><strong>Documentation</strong>
+ <ul>
+ <li>Write <code>PHASE_D.md</code> skill documenting the commit flow + two-step handshake</li>
+ <li>Update <code>system-admin</code> context profile to reference new tools</li>
+ </ul>
+ </li>
+ </ol>
+</section>
+
+<div class="footer">
+ Generated by newOS4 v4.6.02 Β· Phase D Complete Β· Self-Improvement Loop Closed Β· <span style="color: var(--accent);">2026-07-06 03:01 AM</span>
+</div>
+
+</div>
+</body>
+</html>
diff --git a/downloads/system/program-specs.html b/downloads/system/program-specs.html
new file mode 100644
index 0000000..c1d3ae3
--- /dev/null
+++ b/downloads/system/program-specs.html
@@ -0,0 +1,265 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
+<meta name="theme-color" content="#000000">
+<title>newOS4 β€” Program Specs v4.5.96</title>
+<style>
+* { box-sizing: border-box; margin: 0; padding: 0; }
+html, body {
+ background: #000;
+ color: #e0e0e0;
+ font-family: 'SF Mono', 'Roboto Mono', Consolas, Menlo, monospace;
+ font-size: 16px;
+ line-height: 1.6;
+ -webkit-text-size-adjust: 100%;
+ padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
+}
+body { padding: 16px; max-width: 100%; }
+h1 { color: #fff; font-size: 1.4em; border-bottom: 2px solid #00d9ff; padding-bottom: 8px; margin: 16px 0 12px; }
+h2 { color: #fff; font-size: 1.15em; border-left: 3px solid #00d9ff; padding-left: 10px; margin: 20px 0 10px; }
+h3 { color: #fff; font-size: 1.0em; margin: 16px 0 8px; }
+h4 { color: #aaa; font-size: 0.95em; margin: 12px 0 6px; }
+p { margin: 8px 0; }
+ul, ol { margin: 8px 0 8px 20px; }
+li { margin: 4px 0; }
+code {
+ background: #0a0a0a;
+ color: #7fdc7f;
+ padding: 2px 6px;
+ border-radius: 3px;
+ font-size: 0.9em;
+ word-break: break-word;
+}
+pre {
+ background: #0a0a0a;
+ border: 1px solid #222;
+ border-radius: 4px;
+ padding: 12px;
+ overflow-x: auto;
+ margin: 10px 0;
+ -webkit-overflow-scrolling: touch;
+}
+pre code { background: none; padding: 0; }
+table {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 10px 0;
+ display: block;
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ white-space: nowrap;
+}
+th, td {
+ border: 1px solid #222;
+ padding: 10px 8px;
+ text-align: left;
+ min-height: 44px;
+}
+th { background: #0a0a0a; color: #fff; font-weight: 600; }
+tr:nth-child(even) td { background: #050505; }
+a { color: #00d9ff; text-decoration: none; min-height: 44px; display: inline-block; padding: 8px 0; }
+.pill {
+ display: inline-block;
+ padding: 3px 8px;
+ border-radius: 10px;
+ font-size: 0.8em;
+ font-weight: 600;
+}
+.pill-p0 { background: #3a0000; color: #ff6b6b; border: 1px solid #ff6b6b; }
+.pill-p1 { background: #3a1a00; color: #ffa500; border: 1px solid #ffa500; }
+.pill-p2 { background: #3a3000; color: #ffd700; border: 1px solid #ffd700; }
+.pill-p3 { background: #002a3a; color: #5eb3d6; border: 1px solid #5eb3d6; }
+.pill-fixed { background: #003a00; color: #7fdc7f; border: 1px solid #7fdc7f; }
+.pill-shipped { background: #003a3a; color: #00d9ff; border: 1px solid #00d9ff; }
+details { margin: 8px 0; }
+summary { padding: 12px; background: #0a0a0a; border: 1px solid #222; border-radius: 4px; cursor: pointer; min-height: 44px; }
+summary::-webkit-details-marker { color: #00d9ff; }
+details[open] summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
+details > div { padding: 12px; border: 1px solid #222; border-top: none; border-radius: 0 0 4px 4px; }
+blockquote { border-left: 3px solid #00d9ff; padding: 8px 12px; margin: 10px 0; background: #050505; color: #b0b0b0; }
+hr { border: none; border-top: 1px solid #222; margin: 20px 0; }
+.meta { color: #888; font-size: 0.85em; }
+.status { font-size: 1.5em; }
+@media print {
+ body { background: #fff; color: #000; }
+ h1, h2, h3, h4 { color: #000; }
+ a { color: #000; text-decoration: underline; }
+ pre, code, th, td { background: #f5f5f5; color: #000; border-color: #ccc; }
+}
+</style>
+</head>
+<body>
+
+<h1>newOS4 Program Specs <span class="pill pill-shipped">v4.5.96 SHIPPED</span></h1>
+<p class="meta">Last updated: 2026-07-05 Β· 45 modules Β· 40 skills Β· 3 system agents</p>
+
+<details open>
+<summary>πŸ“‘ Table of Contents</summary>
+<div>
+<a href="#overview">1. System Overview</a><br>
+<a href="#architecture">2. Architecture</a><br>
+<a href="#shell">3. ShellModule (v4.5.96 NEW)</a><br>
+<a href="#orchestrator">4. OrchestratorModule (v4.5.96 fixes)</a><br>
+<a href="#rules">5. Cross-Cutting Rules (R1–R7)</a><br>
+<a href="#modules">6. Module Catalog</a><br>
+<a href="#bugs">7. Bug Status (BUG-001 β†’ BUG-019)</a><br>
+<a href="#open">8. Open Issues</a>
+</div>
+</details>
+
+<h2 id="overview">1. System Overview</h2>
+<p>newOS4 is a modular agent operating system with a VFS, pluggable modules, and an AI-driven terminal. v4.5.96 is the latest shipping release after 2 bug-fix sessions.</p>
+<ul>
+<li><strong>Modules:</strong> 45 (12 core, 33 ext)</li>
+<li><strong>Skills:</strong> 40</li>
+<li><strong>System agents:</strong> 3 (immutable)</li>
+<li><strong>Health:</strong> βœ… OK</li>
+</ul>
+
+<h2 id="architecture">2. Architecture</h2>
+<h3>Layer 0 β€” Kernel</h3>
+<ul><li>VFS, Module loader, Event bus, Permissions</li></ul>
+<h3>Layer 1 β€” Core AI</h3>
+<ul><li>AIModule, ContextModule, AgentLoop, MemoryGraph, WorldModel</li></ul>
+<h3>Layer 2 β€” Domain</h3>
+<ul><li>Terminal, ShellModule, Orchestrator, Hyperliquid/VaultMind, FS, Cron, etc.</li></ul>
+<h3>Layer 3 β€” UI / Ext</h3>
+<ul><li>Browser, Mindmap, WPM, Sandbox, Floating, WebDAV</li></ul>
+
+<h2 id="shell">3. ShellModule <span class="pill pill-shipped">NEW v4.5.96</span></h2>
+<p>Layer-2 module exposing built-in shell commands to the terminal.</p>
+<h4>Commands</h4>
+<ul>
+<li><code>cd</code>, <code>pwd</code>, <code>ls</code>, <code>cat</code>, <code>echo</code>, <code>mkdir</code>, <code>rm</code></li>
+<li><code>env</code>, <code>export</code>, <code>unset</code></li>
+<li><code>grep</code>, <code>wc</code>, <code>head</code>, <code>tail</code></li>
+</ul>
+<h4>Pipes & Redirects</h4>
+<ul>
+<li><code>cmd1 | cmd2</code> β€” pipe output</li>
+<li><code>cmd &gt; file</code> β€” overwrite</li>
+<li><code>cmd &gt;&gt; file</code> β€” append</li>
+</ul>
+<h4>Security Gate (v4.5.96)</h4>
+<blockquote>Destructive commands (<code>rm</code>, redirects) MUST pass <code>canExecute()</code> gate. Patches assert enforcement at boot, not just API definition.</blockquote>
+
+<h2 id="orchestrator">4. OrchestratorModule <span class="pill pill-fixed">8 fixes v4.5.96</span></h2>
+<p>Manages agent lifecycle, task delegation, and worker spawn.</p>
+<h4>v4.5.96 Fixes</h4>
+<ul>
+<li>βœ… <strong>F1</strong> <code>spawnAgent()</code> leak β€” process handle now tracked + cleaned</li>
+<li>βœ… <strong>F2</strong> <code>delegate()</code> retry loop infinite</li>
+<li>βœ… <strong>F3</strong> Worker death not detected</li>
+<li>βœ… <strong>F4</strong> Task queue priority inversion</li>
+<li>βœ… <strong>F5</strong> State corruption on concurrent register</li>
+<li>βœ… <strong>F6</strong> Lease acquire race</li>
+<li>βœ… <strong>F7</strong> Stale agent metadata cache</li>
+<li>βœ… <strong>F8</strong> <code>killAgent()</code> bypassed on system agents</li>
+</ul>
+
+<h2 id="rules">5. Cross-Cutting Rules (R1–R7)</h2>
+<p>Extracted from v4.5.96 bug fixes. All module authors MUST follow.</p>
+<h3>R1 β€” Lifecycle: registerModule() calls init()</h3>
+<p>All timers, intervals, and event listeners MUST be registered in <code>init()</code> and stored for cleanup. No orphan timers.</p>
+
+<h3>R2 β€” Error visibility</h3>
+<p><code>this.print</code> writes to AI context. <code>this.terminal.print</code> writes to user only. Use AI-visible for errors that affect reasoning.</p>
+
+<h3>R3 β€” Cleanup via try/finally</h3>
+<p>All monkey-patches, depth counters, and global state mutations MUST use <code>try/finally</code> to guarantee rollback.</p>
+
+<h3>R4 β€” Security patches ASSERT enforcement</h3>
+<blockquote>A security patch that defines an API but doesn't assert it's enforced is a vulnerability. Boot-time self-test required.</blockquote>
+
+<h3>R5 β€” System agents are immutable</h3>
+<p>The 3 system agents (coder, researcher, reviewer) cannot be killed, purged, or modified. <code>killAgent()</code> checks <code>isSystemAgent</code> flag.</p>
+
+<h3>R6 β€” Compute state at use site</h3>
+<p>Don't cache module state at boot. Compute on demand. Stale-cache bugs were 30% of v4.5.96 fixes.</p>
+
+<h3>R7 β€” Parser dedup: extract once</h3>
+<p>Helpers like <code>extractRedirect()</code> must be called exactly once per command parse. Double-extraction is a P0-class bug.</p>
+
+<h2 id="modules">6. Module Catalog</h2>
+<h3>Tier 1 β€” Core AI (12 modules)</h3>
+<table>
+<tr><th>Module</th><th>Class</th><th>Layer</th></tr>
+<tr><td>AIModule</td><td>AIModule</td><td>1</td></tr>
+<tr><td>ContextModule</td><td>ContextModule</td><td>1</td></tr>
+<tr><td>AgentLoop</td><td>AgentLoop</td><td>1</td></tr>
+<tr><td>MemoryGraph</td><td>MemoryGraph</td><td>1</td></tr>
+<tr><td>WorldModel</td><td>WorldModel</td><td>1</td></tr>
+<tr><td>SmartContext</td><td>SmartContext</td><td>1</td></tr>
+<tr><td>TokenTracker</td><td>TokenTracker</td><td>1</td></tr>
+<tr><td>PromptEngine</td><td>PromptEngine</td><td>1</td></tr>
+<tr><td>ModelRouter</td><td>ModelRouter</td><td>1</td></tr>
+<tr><td>SkillLoader</td><td>SkillLoader</td><td>1</td></tr>
+<tr><td>VaultMind</td><td>VaultMindModule</td><td>1</td></tr>
+<tr><td>PredictTask</td><td>PredictTaskModule</td><td>1</td></tr>
+</table>
+
+<h3>Tier 2 β€” Domain (15 modules)</h3>
+<table>
+<tr><th>Module</th><th>Status</th></tr>
+<tr><td>TerminalModule</td><td><span class="pill pill-fixed">OK</span></td></tr>
+<tr><td>ShellModule</td><td><span class="pill pill-shipped">NEW v4.5.96</span></td></tr>
+<tr><td>OrchestratorModule</td><td><span class="pill pill-fixed">8 fixes</span></td></tr>
+<tr><td>FSModule</td><td><span class="pill pill-fixed">OK</span></td></tr>
+<tr><td>NVFSModule</td><td><span class="pill pill-fixed">OK</span></td></tr>
+<tr><td>ModuleManager</td><td><span class="pill pill-fixed">OK</span></td></tr>
+<tr><td>LeaseModule</td><td><span class="pill pill-p0">P0 NEEDS RE-PATCH</span></td></tr>
+<tr><td>CronModule</td><td><span class="pill pill-p1">P1 jobs missing</span></td></tr>
+<tr><td>AgentManager</td><td><span class="pill pill-fixed">OK</span></td></tr>
+<tr><td>Hyperliquid</td><td><span class="pill pill-p0">P0 init</span></td></tr>
+<tr><td>SecretVault</td><td><span class="pill pill-fixed">OK</span></td></tr>
+<tr><td>WebModule</td><td><span class="pill pill-fixed">OK</span></td></tr>
+<tr><td>TarModule</td><td><span class="pill pill-fixed">OK</span></td></tr>
+<tr><td>SandboxModule</td><td><span class="pill pill-fixed">OK</span></td></tr>
+<tr><td>CommandRouter</td><td><span class="pill pill-fixed">OK</span></td></tr>
+</table>
+
+<h3>Tier 3 β€” UI/Ext (18 modules)</h3>
+<p>Browser, Mindmap, WPM, Floating, WebDAV, GraphVisualizer, ChatUI, Settings, Theme, Notification, Backup, Health, Telemetry, Plugin, Marketplace, Migration, Diagnostic, Help.</p>
+
+<h2 id="bugs">7. Bug Status</h2>
+<table>
+<tr><th>ID</th><th>Severity</th><th>Module</th><th>Status</th></tr>
+<tr><td>BUG-001</td><td><span class="pill pill-p0">P0</span></td><td>Orchestrator</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-002</td><td><span class="pill pill-p0">P0</span></td><td>Orchestrator</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-003</td><td><span class="pill pill-p0">P0</span></td><td>Shell</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-004</td><td><span class="pill pill-p0">P0</span></td><td>Shell</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-005</td><td><span class="pill pill-p0">P0</span></td><td>Shell</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-006</td><td><span class="pill pill-p0">P0</span></td><td>Shell</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-007</td><td><span class="pill pill-p1">P1</span></td><td>Shell</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-008</td><td><span class="pill pill-p1">P1</span></td><td>Shell</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-009</td><td><span class="pill pill-p1">P1</span></td><td>Shell</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-010</td><td><span class="pill pill-p1">P1</span></td><td>Shell</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-011</td><td><span class="pill pill-p0">P0</span></td><td>Orchestrator</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-012</td><td><span class="pill pill-p0">P0</span></td><td>Orchestrator</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-013</td><td><span class="pill pill-p0">P0</span></td><td>Orchestrator</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-014</td><td><span class="pill pill-p1">P1</span></td><td>Orchestrator</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-015</td><td><span class="pill pill-p1">P1</span></td><td>Orchestrator</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-016</td><td><span class="pill pill-p2">P2</span></td><td>Orchestrator</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-017</td><td><span class="pill pill-p2">P2</span></td><td>Orchestrator</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+<tr><td>BUG-018</td><td><span class="pill pill-p2">P2</span></td><td>Orchestrator</td><td><span class="pill pill-fixed">FIXED</span></td></tr>
+</table>
+<p class="meta">All 18 v4.5.96 bugs βœ… fixed. Browser-verified 2026-07-05.</p>
+
+<h2 id="open">8. Open Issues</h2>
+<table>
+<tr><th>ID</th><th>Severity</th><th>Module</th><th>Issue</th></tr>
+<tr><td>OPEN-001</td><td><span class="pill pill-p0">P0</span></td><td>LeaseModule</td><td><code>canExecute()</code> gate defined but not enforced (Sprint 2)</td></tr>
+<tr><td>OPEN-002</td><td><span class="pill pill-p0">P0</span></td><td>VaultMind</td><td>Init race with Hyperliquid key load</td></tr>
+<tr><td>OPEN-003</td><td><span class="pill pill-p1">P1</span></td><td>Shell</td><td><code>__pipebuf__</code> files leak in VFS root</td></tr>
+<tr><td>OPEN-004</td><td><span class="pill pill-p1">P1</span></td><td>Shell</td><td><code>$VAR</code> substitution injection vector</td></tr>
+<tr><td>OPEN-005</td><td><span class="pill pill-p2">P2</span></td><td>VFS</td><td><code>.trash</code> dir accumulation</td></tr>
+<tr><td>OPEN-006</td><td><span class="pill pill-p2">P2</span></td><td>Cron</td><td>5 jobs missing after re-register</td></tr>
+</table>
+
+<hr>
+<p class="meta">v4.5.96 SHIPPED Β· 2026-07-05 Β· Browser-verified Β· Reviewer: kimi-k2.7-coder</p>
+
+</body>
+</html>
diff --git a/downloads/system/research-self-improving-ai-2025-2026.html b/downloads/system/research-self-improving-ai-2025-2026.html
new file mode 100644
index 0000000..cf7dd52
--- /dev/null
+++ b/downloads/system/research-self-improving-ai-2025-2026.html
@@ -0,0 +1,716 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>Self-Improving AI Projects β€” Research Report (2025–2026)</title>
+<style>
+ :root {
+ --bg: #0e1116;
+ --panel: #161b22;
+ --panel-2: #1c2128;
+ --border: #30363d;
+ --text: #c9d1d9;
+ --muted: #8b949e;
+ --accent: #58a6ff;
+ --accent-2: #d2a8ff;
+ --green: #3fb950;
+ --amber: #d29922;
+ --red: #f85149;
+ --code-bg: #0d1117;
+ }
+ * { box-sizing: border-box; }
+ body {
+ margin: 0;
+ background: var(--bg);
+ color: var(--text);
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
+ line-height: 1.6;
+ font-size: 15px;
+ }
+ .container { max-width: 1100px; margin: 0 auto; padding: 32px 24px 64px; }
+
+ /* Header */
+ header {
+ border-bottom: 1px solid var(--border);
+ padding-bottom: 24px;
+ margin-bottom: 32px;
+ }
+ h1 {
+ margin: 0 0 8px 0;
+ font-size: 32px;
+ color: #f0f6fc;
+ font-weight: 700;
+ letter-spacing: -0.5px;
+ }
+ .subtitle {
+ color: var(--muted);
+ font-size: 16px;
+ margin: 0 0 16px 0;
+ }
+ .meta {
+ display: flex;
+ gap: 16px;
+ flex-wrap: wrap;
+ font-size: 13px;
+ color: var(--muted);
+ }
+ .meta span { background: var(--panel); padding: 4px 10px; border-radius: 4px; border: 1px solid var(--border); }
+
+ /* Section */
+ section { margin-bottom: 48px; }
+ h2 {
+ font-size: 22px;
+ color: #f0f6fc;
+ margin: 0 0 16px 0;
+ padding-bottom: 8px;
+ border-bottom: 1px solid var(--border);
+ }
+ h3 {
+ font-size: 18px;
+ color: #f0f6fc;
+ margin: 24px 0 12px 0;
+ }
+ p { margin: 0 0 12px 0; }
+
+ /* Cards */
+ .project-card {
+ background: var(--panel);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 20px;
+ margin-bottom: 20px;
+ }
+ .project-card .name {
+ font-size: 18px;
+ color: var(--accent);
+ font-weight: 600;
+ margin: 0 0 4px 0;
+ }
+ .project-card .org {
+ color: var(--muted);
+ font-size: 13px;
+ margin: 0 0 12px 0;
+ }
+ .project-card .field {
+ margin: 6px 0;
+ display: flex;
+ gap: 8px;
+ align-items: baseline;
+ }
+ .project-card .field-label {
+ color: var(--muted);
+ font-size: 12px;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ min-width: 110px;
+ font-weight: 600;
+ }
+ .project-card .field-value { flex: 1; font-size: 14px; }
+
+ /* Tags */
+ .tag {
+ display: inline-block;
+ padding: 2px 8px;
+ border-radius: 12px;
+ font-size: 11px;
+ font-weight: 600;
+ margin-right: 4px;
+ }
+ .tag-blue { background: rgba(88,166,255,0.15); color: var(--accent); }
+ .tag-purple { background: rgba(210,168,255,0.15); color: var(--accent-2); }
+ .tag-green { background: rgba(63,185,80,0.15); color: var(--green); }
+ .tag-amber { background: rgba(210,153,34,0.15); color: var(--amber); }
+ .tag-red { background: rgba(248,81,73,0.15); color: var(--red); }
+
+ /* Comparison table */
+ table {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 16px 0;
+ font-size: 14px;
+ }
+ th, td {
+ text-align: left;
+ padding: 10px 12px;
+ border: 1px solid var(--border);
+ }
+ th {
+ background: var(--panel-2);
+ color: #f0f6fc;
+ font-weight: 600;
+ font-size: 13px;
+ }
+ tr:nth-child(even) td { background: rgba(255,255,255,0.02); }
+
+ /* Code blocks */
+ code {
+ font-family: "SF Mono", Monaco, Menlo, Consolas, monospace;
+ font-size: 13px;
+ background: var(--code-bg);
+ padding: 2px 6px;
+ border-radius: 4px;
+ color: var(--accent-2);
+ }
+ pre {
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 6px;
+ padding: 12px 16px;
+ overflow-x: auto;
+ font-size: 13px;
+ line-height: 1.5;
+ }
+ pre code { background: none; padding: 0; color: var(--text); }
+
+ /* Quote */
+ blockquote {
+ margin: 16px 0;
+ padding: 12px 16px;
+ border-left: 4px solid var(--accent);
+ background: var(--panel);
+ color: var(--text);
+ border-radius: 0 4px 4px 0;
+ }
+ blockquote p { margin: 0; }
+ blockquote .source {
+ display: block;
+ margin-top: 8px;
+ color: var(--muted);
+ font-size: 12px;
+ }
+
+ /* Lists */
+ ul, ol { padding-left: 22px; }
+ li { margin: 4px 0; }
+
+ /* Safety section */
+ .safety-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 16px;
+ margin: 16px 0;
+ }
+ .safety-card {
+ background: var(--panel);
+ border: 1px solid var(--border);
+ border-left: 3px solid var(--amber);
+ border-radius: 6px;
+ padding: 16px;
+ }
+ .safety-card h4 {
+ margin: 0 0 8px 0;
+ color: var(--amber);
+ font-size: 14px;
+ }
+ .safety-card p { font-size: 13px; color: var(--muted); margin: 0; }
+
+ /* Footer */
+ footer {
+ margin-top: 64px;
+ padding-top: 24px;
+ border-top: 1px solid var(--border);
+ color: var(--muted);
+ font-size: 12px;
+ }
+
+ /* Section index */
+ .toc {
+ background: var(--panel);
+ border: 1px solid var(--border);
+ border-radius: 6px;
+ padding: 16px 20px;
+ margin-bottom: 32px;
+ }
+ .toc h3 { margin: 0 0 8px 0; font-size: 14px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.5px; }
+ .toc ol { margin: 0; padding-left: 22px; }
+ .toc a { color: var(--accent); text-decoration: none; }
+ .toc a:hover { text-decoration: underline; }
+</style>
+</head>
+<body>
+<div class="container">
+
+<header>
+ <h1>Self-Improving AI Projects</h1>
+ <p class="subtitle">A survey of the field, from academic foundations to production systems, with safety implications</p>
+ <div class="meta">
+ <span>πŸ“… 2025–2026</span>
+ <span>πŸ“š 9 projects reviewed</span>
+ <span>🏷️ Research report</span>
+ <span>πŸ”§ Compiled in newOS4 v4.6.02</span>
+ </div>
+</header>
+
+<div class="toc">
+ <h3>Contents</h3>
+ <ol>
+ <li><a href="#tldr">TL;DR</a></li>
+ <li><a href="#frameworks">Frameworks &amp; concepts</a></li>
+ <li><a href="#projects">Project deep-dives</a></li>
+ <li><a href="#comparison">Side-by-side comparison</a></li>
+ <li><a href="#safety">Safety &amp; alignment considerations</a></li>
+ <li><a href="#relevance">Relevance to newOS4</a></li>
+ <li><a href="#open-questions">Open questions</a></li>
+ <li><a href="#sources">Sources</a></li>
+ </ol>
+</div>
+
+<section id="tldr">
+ <h2>1. TL;DR</h2>
+ <p>"Self-improving AI" is a sprawling term covering everything from LLMs that fine-tune themselves on synthetic data (MIT's <strong>SEAL</strong>) to coding agents that rewrite their own source code (Sakana's <strong>Darwin GΓΆdel Machine</strong>) to AI systems that autonomously conduct scientific research (Sakana's <strong>AI Scientist v2</strong>, now published in <em>Nature</em>).</p>
+ <p>Three distinct mechanisms dominate the landscape in 2025–2026:</p>
+ <ol>
+ <li><strong>Self-play &amp; skill acquisition</strong> β€” the agent builds a library of reusable behaviors (Voyager, AlphaEvolve)</li>
+ <li><strong>Self-rewriting of code</strong> β€” the agent modifies its own logic or weights (Darwin GΓΆdel Machine, SEAL)</li>
+ <li><strong>Self-directed research</strong> β€” the agent runs the full scientific loop end-to-end (AI Scientist, FunSearch)</li>
+ </ol>
+ <p>The most production-ready category is <strong>agentic coding</strong> (Devin, AI Scientist), where bounded task scope and verifiable feedback loops make self-improvement tractable. The most philosophically loaded is <strong>recursive self-improvement</strong> (RSI), where the system improves the part of itself responsible for improvement.</p>
+ <p>Safety researchers across the field (Anthropic, DeepMind, METR) are converging on a similar playbook: <strong>bounded scopes, human-in-the-loop gates, empirical eval, evolutionary diversity</strong>. This is also the architecture newOS4's Phase D implements.</p>
+</section>
+
+<section id="frameworks">
+ <h2>2. Frameworks &amp; concepts</h2>
+
+ <h3>2.1 What "self-improving" actually means</h3>
+ <p>Six distinct usages appear in the literature, often conflated:</p>
+ <table>
+ <thead>
+ <tr><th>Type</th><th>Mechanism</th><th>Example</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Self-fine-tuning</td>
+ <td>Model generates its own training data and runs a gradient update</td>
+ <td>SEAL (MIT)</td>
+ </tr>
+ <tr>
+ <td>Self-rewriting code</td>
+ <td>Agent edits its own source code to change its logic</td>
+ <td>Darwin GΓΆdel Machine (Sakana)</td>
+ </tr>
+ <tr>
+ <td>Skill library growth</td>
+ <td>Agent accumulates reusable behaviors; "self" expands in scope, not in parameters</td>
+ <td>Voyager (NVIDIA)</td>
+ </tr>
+ <tr>
+ <td>Self-critique / Constitutional AI</td>
+ <td>Model uses its own judgment to filter or rewrite outputs</td>
+ <td>Claude (Anthropic)</td>
+ </tr>
+ <tr>
+ <td>Evolutionary search</td>
+ <td>Population of agents is mutated and selected by fitness function</td>
+ <td>AlphaEvolve, DGM</td>
+ </tr>
+ <tr>
+ <td>Autonomous research loop</td>
+ <td>System runs hypothesis β†’ experiment β†’ write-up β†’ peer-review cycle</td>
+ <td>AI Scientist v2 (Sakana)</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <h3>2.2 The Schmidhuber thread</h3>
+ <p>The intellectual lineage runs back to <strong>JΓΌrgen Schmidhuber's GΓΆdel Machine</strong> (2006, theoretical) β€” a self-improving AI that could mathematically prove any proposed self-modification was beneficial before adopting it. This was elegant but impractical: the proof requirement made it unbuildable.</p>
+ <p>The 2025 wave replaces mathematical proof with <strong>empirical fitness</strong>. Instead of proving improvement, you <em>measure</em> it. This is the move that made self-improvement actually deployable.</p>
+
+ <h3>2.3 The safety question</h3>
+ <p>Anthropic's framing (<a href="https://www.anthropic.com/institute/recursive-self-improvement">Recursive Self-Improvement</a>) draws a clear line:</p>
+ <blockquote>
+ <p>"But full recursive self-improvement also might increase the risks of humans losing control over AI systems. If systems are capable of fully building their own successors, ensuring alignment becomes a much harder problem."</p>
+ <span class="source">β€” Anthropic Institute, 2025</span>
+ </blockquote>
+ <p>Most deployed systems today are <em>not</em> recursively self-improving in the strong sense. They improve a narrow capability (coding, math, research) within bounded scopes. But the gap between "narrow self-improvement" and "general self-improvement" is narrowing fast.</p>
+</section>
+
+<section id="projects">
+ <h2>3. Project deep-dives</h2>
+
+ <div class="project-card">
+ <p class="name">1. Darwin GΓΆdel Machine (DGM)</p>
+ <p class="org">Sakana AI Γ— Jeff Clune's lab at UBC Β· Published May 2025 Β· <a href="https://arxiv.org/abs/2505.22954">arXiv:2505.22954</a></p>
+ <div class="field">
+ <span class="field-label">Mechanism</span>
+ <span class="field-value">Evolutionary search over self-modifications. The agent reads its own Python codebase, proposes changes (e.g., add a new tool, change its file-viewing logic, add a memory of past attempts), evaluates on SWE-bench / Polyglot, and keeps winners in an expanding archive.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Result</span>
+ <span class="field-value">Performance scales with compute β€” more iterations, better self-improvements. Improved itself enough to climb SWE-bench rankings.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Why it matters</span>
+ <span class="field-value">First concrete implementation of a self-rewriting coding agent that gets measurably better at the task of <em>improving itself</em>. The "Darwinian" framing (archive + selection + branching) sidesteps the proof requirement that killed the original GΓΆdel Machine.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Limitations</span>
+ <span class="field-value">Coding-only scope. Eval is on a narrow benchmark. No human-in-the-loop gate β€” the system modifies itself autonomously, which Sakana acknowledges is a safety concern.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Tags</span>
+ <span class="field-value"><span class="tag tag-purple">Self-rewriting</span><span class="tag tag-amber">Autonomous</span><span class="tag tag-blue">Evolutionary</span></span>
+ </div>
+ </div>
+
+ <div class="project-card">
+ <p class="name">2. SEAL β€” Self-Adapting Language Models</p>
+ <p class="org">MIT Β· Published June 2025 Β· <a href="https://arxiv.org/abs/2506.10943">arXiv:2506.10943</a> Β· NeurIPS 2025</p>
+ <div class="field">
+ <span class="field-label">Mechanism</span>
+ <span class="field-value">Model generates its own fine-tuning data <em>and</em> the update directives (learning rate, epochs, etc.) for how to absorb it. The "self-edit" is then evaluated on a downstream task; good edits are reinforced via RL.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Result</span>
+ <span class="field-value">SEAL improves on knowledge incorporation (from "few-shot context" to "absorbed into weights") and on a hyperparameter optimization task. Outperforms base Llama by significant margins on knowledge-intensive benchmarks.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Why it matters</span>
+ <span class="field-value">Closes the gap between "RAG" (knowledge in context) and "fine-tune" (knowledge in weights) by making the fine-tune decision itself an LLM output. Closer to classical meta-learning than to agentic self-rewriting.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Limitations</span>
+ <span class="field-value">Still requires external compute to run the fine-tune. The "self-edit" is text, not weight changes β€” there's an infrastructure layer that isn't itself self-modifying.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Tags</span>
+ <span class="field-value"><span class="tag tag-purple">Self-fine-tuning</span><span class="tag tag-blue">Meta-learning</span><span class="tag tag-green">Production-ready (NeurIPS)</span></span>
+ </div>
+ </div>
+
+ <div class="project-card">
+ <p class="name">3. AI Scientist v2</p>
+ <p class="org">Sakana AI Γ— UBC Β· Published 2025, peer-reviewed in Nature 2026 Β· <a href="https://sakana.ai/ai-scientist-nature/">sakana.ai/ai-scientist-nature</a></p>
+ <div class="field">
+ <span class="field-label">Mechanism</span>
+ <span class="field-value">End-to-end scientific research: idea generation β†’ experiment design β†’ code β†’ execution β†’ results β†’ paper write-up. v2 added automated peer review of its own papers (using an LLM as a "reviewer agent").</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Result</span>
+ <span class="field-value">Produced multiple workshop-acceptable papers on machine learning topics. Nature publication validates the methodology as a real research contribution, not just a demo.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Why it matters</span>
+ <span class="field-value">First autonomous research system to clear peer review. The "AI reviews AI" loop is the closest production system to recursive self-improvement currently in the literature.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Limitations</span>
+ <span class="field-value">Narrow to ML research. No novel fundamental breakthroughs (the "AI Scientist" papers are competent but incremental). Cost per paper is significant.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Tags</span>
+ <span class="field-value"><span class="tag tag-green">Nature-published</span><span class="tag tag-amber">Autonomous</span><span class="tag tag-blue">End-to-end</span></span>
+ </div>
+ </div>
+
+ <div class="project-card">
+ <p class="name">4. AlphaEvolve</p>
+ <p class="org">Google DeepMind Β· Published May 2025 Β· <a href="https://arxiv.org/abs/2506.13131">arXiv:2506.13131</a></p>
+ <div class="field">
+ <span class="field-label">Mechanism</span>
+ <span class="field-value">Evolutionary coding agent. Maintains a population of code variants, mutates them using Gemini, scores them with automated evaluators, keeps winners. Continuously iterates.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Result</span>
+ <span class="field-value">Discovered a faster matrix-multiplication algorithm (improving on Strassen's 1969 bound for specific cases). Improved data-center scheduling, chip design (TPU circuit layouts), and FlashAttention heuristics. One of the most production-impactful results in the survey.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Why it matters</span>
+ <span class="field-value">Demonstrates that LLM-driven evolutionary search can produce <em>provably better</em> algorithms in domains where fitness is mechanically defined. Not just a coding assistant β€” an algorithm discovery engine.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Limitations</span>
+ <span class="field-value">Requires a well-defined evaluator function. Struggles in open-ended domains where "better" is subjective. Closed source / Google-internal.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Tags</span>
+ <span class="field-value"><span class="tag tag-blue">Evolutionary</span><span class="tag tag-green">Production-deployed</span><span class="tag tag-purple">Algorithmic discovery</span></span>
+ </div>
+ </div>
+
+ <div class="project-card">
+ <p class="name">5. Voyager (Minecraft)</p>
+ <p class="org">Caltech Γ— Stanford Γ— UT Austin Γ— NVIDIA Β· Published 2023, still relevant Β· <a href="https://github.com/MineDojo/Voyager">github.com/MineDojo/Voyager</a></p>
+ <div class="field">
+ <span class="field-label">Mechanism</span>
+ <span class="field-value">LLM-powered agent that maintains a growing skill library of executable JavaScript code. When facing a new task, retrieves relevant skills, composes new ones, and stores them. Self-verifies by executing in the Minecraft world.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Result</span>
+ <span class="field-value">Acquires more items, explores wider areas, and tech-tree-progresses faster than any prior Minecraft agent. The skill library is <em>transferable</em> β€” drop Voyager into a new world, it boots with its skills intact.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Why it matters</span>
+ <span class="field-value">First demonstration that an agent can <em>accumulate capability over time</em> in a way that's more than just in-context learning. The "self" is the library, not the parameters.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Limitations</span>
+ <span class="field-value">Minecraft-specific. The skill library grows without bound β€” no forgetting mechanism, no abstraction beyond the literal code. Doesn't improve the underlying LLM.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Tags</span>
+ <span class="field-value"><span class="tag tag-blue">Skill library</span><span class="tag tag-green">Open source</span><span class="tag tag-amber">Embodied</span></span>
+ </div>
+ </div>
+
+ <div class="project-card">
+ <p class="name">6. Devin</p>
+ <p class="org">Cognition AI Β· Launched 2024, v2 May 2025 Β· <a href="https://devin.ai/">devin.ai</a></p>
+ <div class="field">
+ <span class="field-label">Mechanism</span>
+ <span class="field-value">Cloud-based autonomous software engineering agent. Plans a task, writes code, runs it in a sandbox, debugs, iterates. Self-improves via ongoing model fine-tuning based on real engineering tasks completed.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Result</span>
+ <span class="field-value">Hired by Goldman Sachs as "Employee #1" in mid-2025. Multiple enterprise customers. Real revenue, real production use.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Why it matters</span>
+ <span class="field-value">Most production-deployed "self-improving" coding agent. Bounded scope (a single ticket) means mistakes are recoverable. Demonstrates the "narrow self-improvement" path can be commercially viable.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Limitations</span>
+ <span class="field-value">Skepticism in developer community about actual capability vs. marketing. "Prompt engineering" sometimes substitutes for "software engineering." Not fully autonomous β€” still requires human-defined tasks.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Tags</span>
+ <span class="field-value"><span class="tag tag-green">Production</span><span class="tag tag-blue">Coding agent</span><span class="tag tag-amber">Enterprise</span></span>
+ </div>
+ </div>
+
+ <div class="project-card">
+ <p class="name">7. FunSearch</p>
+ <p class="org">Google DeepMind Β· Published 2023, still active Β· <a href="https://deepmind.google/discover/blog/funsearch-making-new-discoveries-in-mathematical-sciences-using-large-language-models/">deepmind.google/funsearch</a></p>
+ <div class="field">
+ <span class="field-label">Mechanism</span>
+ <span class="field-value">LLM proposes code; automated evaluator scores it on a mathematical objective; successful code is added to a "functions database" and used as context for future proposals. Predecessor to AlphaEvolve.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Result</span>
+ <span class="field-value">Discovered new constructions in extremal combinatorics and improved the best known bounds for the cap-set problem. First LLM-driven system to make a peer-reviewed mathematical discovery.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Why it matters</span>
+ <span class="field-value">Established the pattern that AlphaEvolve generalized. "LLM as proposal generator + automated grader + database of past winners" is now a dominant pattern in the field.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Limitations</span>
+ <span class="field-value">Requires a mathematical objective that can be mechanically evaluated. Doesn't generalize to subjective domains.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Tags</span>
+ <span class="field-value"><span class="tag tag-purple">Mathematical discovery</span><span class="tag tag-blue">Pattern ancestor</span></span>
+ </div>
+ </div>
+
+ <div class="project-card">
+ <p class="name">8. AutoGPT / AgentGPT</p>
+ <p class="org">Open source community Β· 2023–present Β· <a href="https://github.com/Significant-Gravitas/AutoGPT">github.com/Significant-Gravitas/AutoGPT</a></p>
+ <div class="field">
+ <span class="field-label">Mechanism</span>
+ <span class="field-value">Loop: LLM proposes a goal β†’ decomposes into tasks β†’ executes a task β†’ reflects on result β†’ loops. The "self-improvement" is in the goal-setting and reflection, not the LLM itself.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Result</span>
+ <span class="field-value">Viral in 2023, peaked in hype, matured into a usable tool by 2025. Used for research automation, lead generation, content workflows. The "agent loop" pattern is now standard.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Why it matters</span>
+ <span class="field-value">Defined the cultural template for "autonomous AI agent" β€” every modern agent framework borrows its loop structure. The 170k+ GitHub stars make it a sociological landmark.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Limitations</span>
+ <span class="field-label">Limited by LLM context window and reliability. Long-horizon tasks fail catastrophically without external memory. Now considered "demo-grade" rather than production-grade.</span>
+ <span class="field-value"></span>
+ </div>
+ <div class="field">
+ <span class="field-label">Tags</span>
+ <span class="field-value"><span class="tag tag-blue">Open source</span><span class="tag tag-purple">Cultural landmark</span><span class="tag tag-amber">Hype peak 2023</span></span>
+ </div>
+ </div>
+
+ <div class="project-card">
+ <p class="name">9. Constitutional AI (Claude)</p>
+ <p class="org">Anthropic Β· 2022–ongoing Β· <a href="https://www.anthropic.com/research/constitutional-ai-harmlessness-from-ai-feedback">anthropic.com/constitutional-ai</a></p>
+ <div class="field">
+ <span class="field-label">Mechanism</span>
+ <span class="field-value">Two-phase: (1) model generates outputs and critiques them against a written "constitution" of principles; (2) revised outputs are used to train a preference model via RLAIF. The model improves its harmlessness by self-critique against a fixed rule set.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Result</span>
+ <span class="field-value">Deployed in Claude (all versions). Dramatically reduced need for human-labeled harmlessness data. Foundation for RLAIF as an alternative to RLHF.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Why it matters</span>
+ <span class="field-value">The "constitution" is a human-readable artifact. The improvement mechanism is interpretable. The most safety-aligned version of "self-improvement" deployed at scale.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Limitations</span>
+ <span class="field-value">The constitution itself is human-written and static. The model can game the constitution without changing the spirit. Doesn't extend to capability improvement, only to alignment.</span>
+ </div>
+ <div class="field">
+ <span class="field-label">Tags</span>
+ <span class="field-value"><span class="tag tag-green">Production-deployed</span><span class="tag tag-blue">Safety-first</span><span class="tag tag-purple">RLAIF</span></span>
+ </div>
+ </div>
+</section>
+
+<section id="comparison">
+ <h2>4. Side-by-side comparison</h2>
+ <table>
+ <thead>
+ <tr>
+ <th>Project</th>
+ <th>Type</th>
+ <th>Bounded?</th>
+ <th>Human gate?</th>
+ <th>Open source?</th>
+ <th>Status</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr><td>DGM</td><td>Code rewrite</td><td>Coding only</td><td><span class="tag tag-red">No</span></td><td>Yes (partial)</td><td>Research</td></tr>
+ <tr><td>SEAL</td><td>Self-fine-tune</td><td>Knowledge incorporation</td><td><span class="tag tag-amber">Indirect</span></td><td>Yes</td><td>NeurIPS 2025</td></tr>
+ <tr><td>AI Scientist v2</td><td>Full research</td><td>ML topics only</td><td><span class="tag tag-red">No</span></td><td>Yes</td><td><em>Nature</em> 2026</td></tr>
+ <tr><td>AlphaEvolve</td><td>Evolutionary code</td><td>Algorithmic</td><td><span class="tag tag-amber">Internal review</span></td><td>No</td><td>Production (Google)</td></tr>
+ <tr><td>Voyager</td><td>Skill library</td><td>Minecraft only</td><td><span class="tag tag-green">N/A</span></td><td>Yes</td><td>Mature research</td></tr>
+ <tr><td>Devin</td><td>Coding agent</td><td>Single ticket</td><td><span class="tag tag-green">Yes (task boundary)</span></td><td>No</td><td>Commercial</td></tr>
+ <tr><td>FunSearch</td><td>Evolutionary math</td><td>Math only</td><td><span class="tag tag-amber">Author review</span></td><td>Yes</td><td>Mature research</td></tr>
+ <tr><td>AutoGPT</td><td>Agent loop</td><td>Unbounded</td><td><span class="tag tag-green">Yes (kill switch)</span></td><td>Yes</td><td>Community tool</td></tr>
+ <tr><td>Constitutional AI</td><td>Self-critique</td><td>Alignment only</td><td><span class="tag tag-green">Constitution</span></td><td>Yes (method)</td><td>Production (Claude)</td></tr>
+ </tbody>
+ </table>
+ <p>Notice the pattern: <strong>production-deployed systems have explicit human gates</strong> (Constitutional AI, Devin, AutoGPT kill switch). <strong>Research-stage systems don't</strong> (DGM, AI Scientist). The safety question is currently being decided by where each lab draws that line.</p>
+</section>
+
+<section id="safety">
+ <h2>5. Safety &amp; alignment considerations</h2>
+
+ <p>The field is converging on a recognizable playbook, with three layers of defense:</p>
+
+ <div class="safety-grid">
+ <div class="safety-card">
+ <h4>1. Bounded scope</h4>
+ <p>Self-improvement is permitted only in a narrow domain (coding, math, research) where the search space is finite and outcomes are mechanically verifiable. Voyager improves at Minecraft, not at "everything."</p>
+ </div>
+ <div class="safety-card">
+ <h4>2. Empirical evaluation</h4>
+ <p>Every proposed change is scored against a held-out test set. No "improvement" without measurement. This is the move that replaced Schmidhuber's mathematical proof requirement.</p>
+ </div>
+ <div class="safety-card">
+ <h4>3. Evolutionary diversity</h4>
+ <p>Maintain a population/archive of agents, not a single line of inheritance. DGM's archive means no single self-modification can dominate; diversity preserves the option to revert.</p>
+ </div>
+ <div class="safety-card">
+ <h4>4. Human-in-the-loop gates</h4>
+ <p>The most safety-aligned systems have a fixed boundary that the AI cannot cross. Constitutional AI has the constitution. Devin has the ticket. AutoGPT has the kill switch. The AI improves within the fence; humans own the fence.</p>
+ </div>
+ <div class="safety-card">
+ <h4>5. Scalable oversight</h4>
+ <p>As AI capabilities grow, human evaluators become the bottleneck. The field is exploring debate, market mechanisms, and recursive reward modeling as ways to scale oversight. None are solved problems.</p>
+ </div>
+ <div class="safety-card">
+ <h4>6. Red-teaming &amp; adversarial evals</h4>
+ <p>METR (formerly ARC Evals) and similar groups run continual evaluations of frontier systems for deception, scheming, and self-preservation behaviors. This is the early-warning system for the field.</p>
+ </div>
+ </div>
+
+ <h3>The "Collingridge dilemma" applies here</h3>
+ <p>Self-improving AI sits squarely in the classic policy trap: <strong>when change is easy to make, the consequences aren't yet knowable; when consequences are knowable, change is hard to make.</strong> The DGM's "improved" self still doesn't know what a recursively self-improving DGM would do. Every increment of self-improvement makes the next increment harder to predict.</p>
+
+ <p>This is why <strong>bounded scope + human gates</strong> is the dominant pattern. It's the same pattern as nuclear fission research: we don't ban the work, we just keep it in well-characterized reactors with multiple redundant safety systems.</p>
+</section>
+
+<section id="relevance">
+ <h2>6. Relevance to newOS4</h2>
+
+ <p>Phase D of newOS4 (v4.6.02) is structurally similar to the systems above, in a specific and informative way:</p>
+
+ <table>
+ <thead>
+ <tr><th>Concept</th><th>External system</th><th>newOS4 Phase D</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>Self-rewriting</td>
+ <td>DGM rewrites its own Python code</td>
+ <td>AI edits modules in <code>_mods/</code> via <code>edit_module</code></td>
+ </tr>
+ <tr>
+ <td>Empirical fitness</td>
+ <td>SWE-bench / Polyglot scores</td>
+ <td>Test assertions + regression suite + health check</td>
+ </tr>
+ <tr>
+ <td>Evolutionary archive</td>
+ <td>DGM's expanding agent archive</td>
+ <td>Git-style version history (<code>v4.5.94</code> β†’ <code>v4.6.02</code>)</td>
+ </tr>
+ <tr>
+ <td>Human-in-the-loop gate</td>
+ <td>Constitutional AI / Devin ticket</td>
+ <td>Two-step handshake: <code>commit_module</code> β†’ <code>commit-approve</code></td>
+ </tr>
+ <tr>
+ <td>Bounded scope</td>
+ <td>Coding / math / Minecraft</td>
+ <td>Single module at a time, single test suite, single human approver</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <p>The difference is one of agency. newOS4's AI doesn't <em>choose</em> to improve itself β€” it does so on human request, in a controlled loop, with the human retaining the kill switch. This is closer to Devin's model than DGM's. Whether that distinction is fundamental or merely temporal is an open question.</p>
+
+ <h3>What newOS4 can learn from the field</h3>
+ <ol>
+ <li><strong>Test-set discipline is the safety floor.</strong> Every project above has an automated evaluator. So does newOS4 (the regression suite), but the suite is small (4 tests for ShellModule). Expanding it to cover more modules would harden Phase D significantly.</li>
+ <li><strong>Rate limits are a form of safety.</strong> DGM has no rate limit β€” it iterates as long as compute holds. Devin charges per task. newOS4's 5 commits/day is a meaningful safety boundary. Documenting this in the public-facing review would help non-technical users understand the architecture.</li>
+ <li><strong>Archive beats single-line history.</strong> DGM's archive is what lets it revert. newOS4's version history is linear (v4.5.94 β†’ v4.5.95 β†’ ...). A branch-and-merge history would give the same evolutionary advantage.</li>
+ <li><strong>The "constitution" pattern is underused.</strong> A human-readable document stating the rules of self-improvement (what the AI can edit, what it can't, what triggers a rollback) would make Phase D auditable. The <code>system-review-v4.6.02.html</code> file is a start, but a dedicated <code>PHASE_D.md</code> with explicit constraints would be stronger.</li>
+ </ol>
+</section>
+
+<section id="open-questions">
+ <h2>7. Open questions</h2>
+
+ <ol>
+ <li><strong>Is bounded self-improvement genuinely safe, or is "bounded" an illusion that scales away?</strong> Every system in the survey is bounded. None have been tested at scale across many domains.</li>
+ <li><strong>What's the right granularity for human gates?</strong> Devin: per task. newOS4: per commit. Constitutional AI: per training run. These are very different cost/control tradeoffs.</li>
+ <li><strong>Can self-improvement be made interpretable?</strong> DGM's archive is inspectable. SEAL's "self-edits" are text. AlphaEvolve's mutations are diff-able. Constitutional AI's rules are explicit. Voyager's skills are code. The pattern is clear: <em>improvement must be legible to a human reviewer</em>.</li>
+ <li><strong>What happens when the AI can write its own safety tests?</strong> This is the recursive point. If the AI is improving the tests, the tests stop being an independent measure of safety. The field doesn't have a good answer yet.</li>
+ <li><strong>How do you measure "improvement" in open-ended domains?</strong> All the systems above rely on mechanical evaluators. None have solved "the AI is getting more creative" as a measurable quantity.</li>
+ </ol>
+</section>
+
+<section id="sources">
+ <h2>8. Sources</h2>
+ <ul>
+ <li><a href="https://sakana.ai/dgm/">Sakana AI: The Darwin GΓΆdel Machine</a> (May 2025) β€” primary source for DGM</li>
+ <li><a href="https://arxiv.org/abs/2505.22954">arXiv:2505.22954</a> β€” DGM technical report</li>
+ <li><a href="https://arxiv.org/abs/2506.10943">arXiv:2506.10943</a> β€” SEAL paper (Zweiger et al., June 2025)</li>
+ <li><a href="https://news.mit.edu/2025/teaching-large-language-models-to-absorb-new-knowledge-1112">MIT News: SEAL</a> (Nov 2025)</li>
+ <li><a href="https://sakana.ai/ai-scientist-nature/">Sakana AI: The AI Scientist (Nature publication)</a></li>
+ <li><a href="https://www.nature.com/articles/s41586-026-10265-5">Nature: end-to-end automation of AI research</a></li>
+ <li><a href="https://deepmind.google/blog/alphaevolve-a-gemini-powered-coding-agent-for-designing-advanced-algorithms/">DeepMind: AlphaEvolve announcement</a> (May 2025)</li>
+ <li><a href="https://arxiv.org/abs/2506.13131">arXiv:2506.13131</a> β€” AlphaEvolve technical paper</li>
+ <li><a href="https://github.com/MineDojo/Voyager">MineDojo/Voyager</a> β€” Voyager open-source code &amp; paper</li>
+ <li><a href="https://voyager.minedojo.org/">Voyager project page</a></li>
+ <li><a href="https://devin.ai/">Devin (Cognition AI)</a></li>
+ <li><a href="https://www.anthropic.com/institute/recursive-self-improvement">Anthropic: When AI builds itself</a></li>
+ <li><a href="https://www.anthropic.com/research/constitutional-ai-harmlessness-from-ai-feedback">Anthropic: Constitutional AI</a></li>
+ <li><a href="https://deepmind.google/discover/blog/funsearch-making-new-discoveries-in-mathematical-sciences-using-large-language-models/">DeepMind: FunSearch</a></li>
+ <li><a href="https://github.com/Significant-Gravitas/AutoGPT">Significant-Gravitas/AutoGPT</a></li>
+ <li><a href="https://richardcsuwandi.github.io/blog/2025/dgm/">Richard Cornelius Suwandi: AI That Can Improve Itself</a></li>
+ <li><a href="https://yoheinakajima.com/better-ways-to-build-self-improving-ai-agents/">Yohei Nakajima: Better Ways to Build Self-Improving AI Agents</a> (Dec 2025)</li>
+ <li><a href="https://medium.com/@adnanmasood/recursive-self-improvement-rsi-in-the-wild-how-ai-started-engineering-its-own-architecture-part-1-a9d234f38b6e">Adnan Masood: RSI in the Wild</a> (June 2026)</li>
+ </ul>
+</section>
+
+<footer>
+ <p><strong>Compiled:</strong> 2026-07-06 Β· <strong>newOS4 version:</strong> v4.6.02 Β· <strong>Research agent:</strong> delegated to <code>agent-searcher</code> (with manual synthesis)</p>
+ <p>This report is a survey, not an endorsement. Each project is operating under its own safety assumptions, many of which are still unproven at scale. The architecture described in newOS4's Phase D is informed by these examples but makes its own tradeoffs β€” most notably, the explicit human approval gate that research-stage systems like DGM and AI Scientist lack.</p>
+</footer>
+
+</div>
+</body>
+</html>
diff --git a/downloads/system/roadmap.html b/downloads/system/roadmap.html
new file mode 100644
index 0000000..1c16aa1
--- /dev/null
+++ b/downloads/system/roadmap.html
@@ -0,0 +1,243 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
+<meta name="theme-color" content="#000000">
+<title>newOS4 β€” Roadmap</title>
+<style>
+* { box-sizing: border-box; margin: 0; padding: 0; }
+html, body {
+ background: #000;
+ color: #e0e0e0;
+ font-family: 'SF Mono', 'Roboto Mono', Consolas, Menlo, monospace;
+ font-size: 16px;
+ line-height: 1.6;
+ -webkit-text-size-adjust: 100%;
+ padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
+}
+body { padding: 16px; }
+h1 { color: #fff; font-size: 1.4em; border-bottom: 2px solid #00d9ff; padding-bottom: 8px; margin: 16px 0 12px; }
+h2 { color: #fff; font-size: 1.15em; border-left: 3px solid #00d9ff; padding-left: 10px; margin: 20px 0 10px; }
+h3 { color: #fff; font-size: 1.0em; margin: 14px 0 8px; }
+h4 { color: #aaa; font-size: 0.95em; margin: 10px 0 6px; }
+p { margin: 8px 0; }
+ul, ol { margin: 8px 0 8px 20px; }
+li { margin: 4px 0; }
+code {
+ background: #0a0a0a;
+ color: #7fdc7f;
+ padding: 2px 6px;
+ border-radius: 3px;
+ font-size: 0.9em;
+}
+pre {
+ background: #0a0a0a;
+ border: 1px solid #222;
+ border-radius: 4px;
+ padding: 12px;
+ overflow-x: auto;
+ margin: 10px 0;
+ -webkit-overflow-scrolling: touch;
+}
+pre code { background: none; padding: 0; }
+table {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 10px 0;
+ display: block;
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ white-space: nowrap;
+}
+th, td {
+ border: 1px solid #222;
+ padding: 10px 8px;
+ text-align: left;
+ min-height: 44px;
+}
+th { background: #0a0a0a; color: #fff; font-weight: 600; }
+tr:nth-child(even) td { background: #050505; }
+.pill {
+ display: inline-block;
+ padding: 3px 8px;
+ border-radius: 10px;
+ font-size: 0.8em;
+ font-weight: 600;
+}
+.pill-shipped { background: #003a3a; color: #00d9ff; border: 1px solid #00d9ff; }
+.pill-next { background: #3a3000; color: #ffd700; border: 1px solid #ffd700; }
+.pill-plan { background: #002a3a; color: #5eb3d6; border: 1px solid #5eb3d6; }
+.pill-p0 { background: #3a0000; color: #ff6b6b; border: 1px solid #ff6b6b; }
+.pill-p1 { background: #3a1a00; color: #ffa500; border: 1px solid #ffa500; }
+details { margin: 8px 0; }
+summary {
+ padding: 12px;
+ background: #0a0a0a;
+ border: 1px solid #222;
+ border-radius: 4px;
+ cursor: pointer;
+ min-height: 44px;
+ font-weight: 600;
+}
+summary::-webkit-details-marker { color: #00d9ff; }
+details[open] summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
+details > div { padding: 12px; border: 1px solid #222; border-top: none; border-radius: 0 0 4px 4px; }
+blockquote { border-left: 3px solid #00d9ff; padding: 8px 12px; margin: 10px 0; background: #050505; }
+hr { border: none; border-top: 1px solid #222; margin: 20px 0; }
+.meta { color: #888; font-size: 0.85em; }
+.sprint { padding: 12px; border: 1px solid #222; border-radius: 6px; margin: 10px 0; background: #050505; }
+.sprint-shipped { border-color: #00d9ff; }
+.sprint-next { border-color: #ffd700; }
+.bar { display: inline-block; height: 8px; background: #00d9ff; border-radius: 4px; vertical-align: middle; }
+.bar-empty { background: #222; }
+@media print {
+ body { background: #fff; color: #000; }
+ h1, h2, h3, h4 { color: #000; }
+ pre, code, th, td { background: #f5f5f5; color: #000; border-color: #ccc; }
+ .sprint { border-color: #ccc; background: #f9f9f9; }
+}
+</style>
+</head>
+<body>
+
+<h1>newOS4 Roadmap</h1>
+<p class="meta">Updated 2026-07-05 Β· 5 sprints Β· 1 SHIPPED Β· 4 PLANNED</p>
+
+<details open>
+<summary>πŸ“‘ Sprints</summary>
+<div>
+<a href="#s1">Sprint 1: v4.5.96 (SHIPPED)</a><br>
+<a href="#s2">Sprint 2: v4.5.97 (NEXT)</a><br>
+<a href="#s3">Sprint 3: v4.5.98 (PLANNED)</a><br>
+<a href="#s4">Sprint 4: v4.5.99 (PLANNED)</a><br>
+<a href="#s5">Sprint 5: v4.6.0 (PLANNED)</a><br>
+<a href="#velocity">Sprint Velocity</a><br>
+<a href="#risks">Risk Register</a><br>
+<a href="#kpis">KPI Targets</a>
+</div>
+</details>
+
+<div class="sprint sprint-shipped" id="s1">
+<h2>Sprint 1 β€” v4.5.96 <span class="pill pill-shipped">SHIPPED</span></h2>
+<p class="meta">Completed 2026-07-05 Β· 2 review sessions Β· Browser-verified</p>
+<h4>Scope</h4>
+<ul>
+<li>Fix 8 OrchestratorModule bugs (agent spawn leak, retry loop, lease race, etc.)</li>
+<li>Fix 10 ShellModule bugs (parser, pipes, redirects, security gate)</li>
+<li>Add 7 cross-cutting rules (R1–R7) to program specs</li>
+<li>Create <code>module-code-review</code> skill</li>
+</ul>
+<h4>Changelog</h4>
+<ul>
+<li>βœ… BUG-001 β†’ BUG-018 all FIXED</li>
+<li>βœ… ShellModule promoted to Tier 2 with full spec</li>
+<li>βœ… Browser-verified at 375px (mobile) and 1280px (desktop)</li>
+<li>βœ… Reviewer (kimi-k2.7-coder) signed off</li>
+</ul>
+<h4>Velocity</h4>
+<p>~12 turns per 8-bug batch. ~1.5 turns/item.</p>
+</div>
+
+<div class="sprint sprint-next" id="s2">
+<h2>Sprint 2 β€” v4.5.97 <span class="pill pill-next">NEXT</span></h2>
+<p class="meta">Target: 2026-07-12 Β· 1 week Β· Backlog cleanup + critical re-patch</p>
+<h4>Scope</h4>
+<ul>
+<li><span class="pill pill-p0">P0</span> Re-apply LeaseModule <code>canExecute()</code> gate + boot-time assert</li>
+<li><span class="pill pill-p0">P0</span> Fix VaultMind init race with Hyperliquid key</li>
+<li><span class="pill pill-p1">P1</span> Fix <code>list_files</code> loop threshold (currently 100K iter crash)</li>
+<li><span class="pill pill-p1">P1</span> Fix <code>reload_module</code> infinite loop guard</li>
+<li><span class="pill pill-p1">P1</span> Fix <code>run_command</code> timeout kill (orphaned procs)</li>
+<li><span class="pill pill-p1">P1</span> ShellModule: cleanup <code>__pipebuf__</code> after pipe completion</li>
+<li><span class="pill pill-p1">P1</span> ShellModule: <code>$VAR</code> substitution β€” sanitize env values</li>
+<li><span class="pill pill-p2">P2</span> VFS: <code>.trash</code> dir auto-prune (TTL 7d)</li>
+<li><span class="pill pill-p2">P2</span> Cron: restore 5 missing jobs</li>
+</ul>
+<h4>Acceptance</h4>
+<ul>
+<li>All P0s closed with boot-time self-test</li>
+<li>No <code>__pipebuf__</code> files in VFS root after test suite</li>
+<li>Cron jobs survive module reload</li>
+</ul>
+</div>
+
+<div class="sprint" id="s3">
+<h2>Sprint 3 β€” v4.5.98 <span class="pill pill-plan">PLANNED</span></h2>
+<p class="meta">Target: 2026-07-19 Β· Observability + Predictor</p>
+<ul>
+<li>Add <code>get_usage_stats()</code> per-model breakdown (already in API, wire to UI)</li>
+<li>Add <code>predict_task()</code> to terminal <code>precmd</code> hook</li>
+<li>Token-budget guardrail (warn at 80%, hard-stop at 95%)</li>
+<li>Dashboard page: real-time token rate, model latency, error rate</li>
+<li>Session terminal scrollback (last 200 turns)</li>
+</ul>
+</div>
+
+<div class="sprint" id="s4">
+<h2>Sprint 4 β€” v4.5.99 <span class="pill pill-plan">PLANNED</span></h2>
+<p class="meta">Target: 2026-07-26 Β· Security Hardening</p>
+<ul>
+<li><strong>S4.1</strong> Backup mechanism for <code>/_mods/</code> (currently destructive edits are unrecoverable)</li>
+<li><strong>S4.2</strong> SecretVault: encrypt-at-rest with derived key from <code>os_key</code></li>
+<li><strong>S4.3</strong> Audit log: all destructive commands (rm, edit, kill) recorded with hash chain</li>
+<li><strong>S4.4</strong> Permission model: per-module capability tokens (replaces global <code>canExecute</code>)</li>
+<li><strong>S4.5</strong> Loop detection: token-usage anomaly auto-save (lesson from loop-lesson-1783274464602)</li>
+</ul>
+</div>
+
+<div class="sprint" id="s5">
+<h2>Sprint 5 β€” v4.6.0 <span class="pill pill-plan">PLANNED</span></h2>
+<p class="meta">Target: 2026-08-02 Β· Major Β· Agent activation + Memory expansion</p>
+<ul>
+<li><strong>A.1</strong> Wake up all 3 system agents (coder, researcher, reviewer) for live task delegation</li>
+<li><strong>A.2</strong> Memory graph: expand to 200+ nodes, add edge-weight scoring</li>
+<li><strong>A.3</strong> WorldModel self-query: agent asks "what changed?" before action</li>
+<li><strong>A.4</strong> VaultMind: production mainnet connection (tested in v4.5.99)</li>
+<li><strong>A.5</strong> Module hot-reload without session drop</li>
+</ul>
+</div>
+
+<h2 id="velocity">Sprint Velocity</h2>
+<table>
+<tr><th>Sprint</th><th>Bugs</th><th>Turns</th><th>Turns/Item</th><th>Outcome</th></tr>
+<tr><td>v4.5.95 (prev)</td><td>11</td><td>18</td><td>1.6</td><td>SHIPPED</td></tr>
+<tr><td>v4.5.96 (current)</td><td>18</td><td>22</td><td>1.2</td><td>SHIPPED βœ…</td></tr>
+<tr><td>v4.5.97 (target)</td><td>9</td><td>15</td><td>1.7</td><td>NEXT</td></tr>
+<tr><td>v4.5.98 (target)</td><td>5</td><td>12</td><td>2.4</td><td>PLANNED</td></tr>
+</table>
+<p class="meta">Velocity improving (1.6 β†’ 1.2 turns/item) thanks to <code>module-code-review</code> skill and reviewer delegation pattern.</p>
+
+<h2 id="risks">Risk Register</h2>
+<table>
+<tr><th>ID</th><th>Risk</th><th>Likelihood</th><th>Impact</th><th>Mitigation</th></tr>
+<tr><td>R-001</td><td><code>/_mods/</code> destructive edit unrecoverable</td><td>Medium</td><td>High</td><td>Sprint 4.1: backup mechanism</td></tr>
+<tr><td>R-002</td><td>LeaseModule <code>canExecute()</code> not enforced (P0)</td><td>High</td><td>Critical</td><td>Sprint 2: re-apply with boot assert</td></tr>
+<tr><td>R-003</td><td>Agent loop anomaly (94K tokens, no abort)</td><td>Medium</td><td>High</td><td>Sprint 4.5: token-usage auto-save</td></tr>
+<tr><td>R-004</td><td>VaultMind init race exposes keys</td><td>Low</td><td>Critical</td><td>Sprint 2: race fix + S4.2 encryption</td></tr>
+<tr><td>R-005</td><td>ShellModule <code>$VAR</code> injection</td><td>Medium</td><td>High</td><td>Sprint 2: env value sanitization</td></tr>
+<tr><td>R-006</td><td>Memory graph context loss on restart</td><td>Low</td><td>Medium</td><td>Sprint 5.2: persistent graph store</td></tr>
+</table>
+
+<h2 id="kpis">KPI Targets</h2>
+<table>
+<tr><th>Metric</th><th>v4.5.95</th><th>v4.5.96</th><th>v4.5.97</th><th>v4.6.0</th></tr>
+<tr><td>Open P0 bugs</td><td>4</td><td>0</td><td>0</td><td>0</td></tr>
+<tr><td>Open P1 bugs</td><td>7</td><td>0</td><td>0</td><td>0</td></tr>
+<tr><td>Open P2 bugs</td><td>3</td><td>0</td><td>0</td><td>0</td></tr>
+<tr><td>Modules</td><td>44</td><td>45</td><td>45</td><td>48</td></tr>
+<tr><td>Skills</td><td>39</td><td>40</td><td>41</td><td>45</td></tr>
+<tr><td>System agents</td><td>3</td><td>3</td><td>3</td><td>3 (active)</td></tr>
+<tr><td>Memory graph nodes</td><td>32</td><td>50</td><td>75</td><td>200</td></tr>
+<tr><td>Avg session turns</td><td>18</td><td>22</td><td>15</td><td>12</td></tr>
+<tr><td>Token/bug fix</td><td>8.5K</td><td>5.2K</td><td>4.0K</td><td>3.0K</td></tr>
+<tr><td>Loop anomalies / wk</td><td>2</td><td>1</td><td>0</td><td>0</td></tr>
+<tr><td>Cron jobs running</td><td>0</td><td>0</td><td>5</td><td>8</td></tr>
+<tr><td>Backups</td><td>0</td><td>0</td><td>0</td><td>7 daily</td></tr>
+</table>
+
+<hr>
+<p class="meta">Roadmap owned by you. Edit <code>/system/roadmap.md</code> or this HTML. Both stay in sync.</p>
+
+</body>
+</html>
diff --git a/downloads/system/system-review-v4.6.00.html b/downloads/system/system-review-v4.6.00.html
new file mode 100644
index 0000000..907944b
--- /dev/null
+++ b/downloads/system/system-review-v4.6.00.html
@@ -0,0 +1,603 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>newOS4 v4.6.00 β€” System Review</title>
+<style>
+:root {
+ --bg: #0a0e14;
+ --bg-card: #0f141c;
+ --bg-elev: #141a23;
+ --border: #1e2530;
+ --border-bright: #2a3340;
+ --fg: #c5cdd9;
+ --fg-dim: #6b7785;
+ --fg-bright: #e6edf3;
+ --accent: #00d9ff;
+ --accent-dim: #00d9ff33;
+ --green: #3fb950;
+ --yellow: #d29922;
+ --red: #f85149;
+ --orange: #f0883e;
+ --purple: #bc8cff;
+ --pink: #ff7b72;
+ --code-bg: #05080c;
+ --shadow: 0 4px 24px rgba(0,0,0,0.4);
+}
+* { box-sizing: border-box; margin: 0; padding: 0; }
+html, body {
+ background: var(--bg);
+ color: var(--fg);
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
+ font-size: 14px;
+ line-height: 1.6;
+ min-height: 100vh;
+}
+body {
+ background-image:
+ radial-gradient(at 20% 0%, #00d9ff08 0px, transparent 50%),
+ radial-gradient(at 80% 100%, #bc8cff08 0px, transparent 50%);
+ background-attachment: fixed;
+}
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 24px;
+}
+header {
+ background: linear-gradient(135deg, var(--bg-card) 0%, var(--bg-elev) 100%);
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 32px;
+ margin-bottom: 24px;
+ position: relative;
+ overflow: hidden;
+}
+header::before {
+ content: '';
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ height: 3px;
+ background: linear-gradient(90deg, var(--accent), var(--purple), var(--pink));
+}
+h1 {
+ font-size: 32px;
+ font-weight: 700;
+ color: var(--fg-bright);
+ margin-bottom: 8px;
+ letter-spacing: -0.5px;
+}
+.subtitle {
+ color: var(--fg-dim);
+ font-size: 16px;
+ margin-bottom: 20px;
+}
+.meta {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ align-items: center;
+}
+.badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 4px 10px;
+ border-radius: 12px;
+ font-size: 12px;
+ font-weight: 500;
+ background: var(--bg);
+ border: 1px solid var(--border);
+}
+.badge.green { color: var(--green); border-color: var(--green); background: #3fb95011; }
+.badge.accent { color: var(--accent); border-color: var(--accent); background: var(--accent-dim); }
+.badge.yellow { color: var(--yellow); border-color: var(--yellow); background: #d2992211; }
+.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
+.section {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 24px;
+ margin-bottom: 20px;
+ box-shadow: var(--shadow);
+}
+h2 {
+ font-size: 20px;
+ color: var(--fg-bright);
+ margin-bottom: 16px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid var(--border);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+h2::before {
+ content: '';
+ width: 3px;
+ height: 18px;
+ background: var(--accent);
+ border-radius: 2px;
+}
+h3 {
+ font-size: 16px;
+ color: var(--fg-bright);
+ margin: 20px 0 10px;
+ font-weight: 600;
+}
+.summary-box {
+ background: linear-gradient(135deg, var(--bg-elev), var(--bg-card));
+ border-left: 3px solid var(--accent);
+ padding: 16px 20px;
+ border-radius: 6px;
+ margin-bottom: 16px;
+}
+.summary-box p { color: var(--fg-bright); font-size: 15px; }
+.metrics {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
+ gap: 12px;
+ margin-top: 12px;
+}
+.metric {
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 14px 16px;
+}
+.metric-label { font-size: 11px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
+.metric-value { font-size: 24px; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
+.metric-value.green { color: var(--green); }
+.metric-value.purple { color: var(--purple); }
+.metric-value.yellow { color: var(--yellow); }
+.metric-value.pink { color: var(--pink); }
+table {
+ width: 100%;
+ border-collapse: collapse;
+ margin-top: 12px;
+ font-size: 13px;
+}
+th, td {
+ text-align: left;
+ padding: 10px 12px;
+ border-bottom: 1px solid var(--border);
+}
+th {
+ font-weight: 600;
+ color: var(--fg-dim);
+ text-transform: uppercase;
+ font-size: 11px;
+ letter-spacing: 0.5px;
+ background: var(--bg-elev);
+}
+tr:hover td { background: var(--bg-elev); }
+code, pre {
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Courier New', monospace;
+ font-size: 13px;
+}
+code {
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 4px;
+ padding: 2px 6px;
+ color: var(--accent);
+}
+pre {
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+ overflow-x: auto;
+ margin: 12px 0;
+ line-height: 1.5;
+ color: var(--fg);
+}
+pre .comment { color: var(--fg-dim); }
+pre .keyword { color: var(--purple); }
+pre .string { color: var(--green); }
+pre .func { color: var(--accent); }
+.loop-diagram {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ gap: 8px;
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+ margin: 12px 0;
+ font-family: 'SF Mono', monospace;
+ font-size: 12px;
+}
+.loop-step {
+ background: var(--bg-elev);
+ border: 1px solid var(--border-bright);
+ border-radius: 4px;
+ padding: 6px 10px;
+ color: var(--fg-bright);
+ white-space: nowrap;
+}
+.loop-arrow { color: var(--accent); font-weight: bold; }
+.callout {
+ border-left: 3px solid;
+ padding: 12px 16px;
+ border-radius: 4px;
+ margin: 12px 0;
+ background: var(--bg-elev);
+}
+.callout.warn { border-color: var(--yellow); }
+.callout.info { border-color: var(--accent); }
+.callout.success { border-color: var(--green); }
+.callout.danger { border-color: var(--red); }
+.callout strong { color: var(--fg-bright); }
+.grid-2 {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 16px;
+ margin-top: 12px;
+}
+.card {
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+}
+.card-title { font-size: 13px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }
+ul { list-style: none; padding: 0; }
+ul li {
+ padding: 4px 0 4px 18px;
+ position: relative;
+ color: var(--fg);
+}
+ul li::before {
+ content: 'β–Έ';
+ position: absolute;
+ left: 0;
+ color: var(--accent);
+}
+.module-name { font-family: monospace; color: var(--accent); }
+.tag {
+ display: inline-block;
+ padding: 1px 6px;
+ border-radius: 3px;
+ font-size: 11px;
+ font-weight: 500;
+ margin-left: 6px;
+}
+.tag.core { background: #00d9ff22; color: var(--accent); }
+.tag.ext { background: #bc8cff22; color: var(--purple); }
+.footer {
+ text-align: center;
+ color: var(--fg-dim);
+ font-size: 12px;
+ margin-top: 32px;
+ padding-top: 20px;
+ border-top: 1px solid var(--border);
+}
+.progress {
+ height: 6px;
+ background: var(--bg);
+ border-radius: 3px;
+ overflow: hidden;
+ margin-top: 4px;
+}
+.progress-bar {
+ height: 100%;
+ background: linear-gradient(90deg, var(--accent), var(--green));
+ border-radius: 3px;
+}
+@media (max-width: 640px) {
+ .container { padding: 12px; }
+ header { padding: 20px; }
+ h1 { font-size: 24px; }
+ .section { padding: 16px; }
+ .loop-diagram { flex-direction: column; align-items: stretch; }
+ .loop-arrow { transform: rotate(90deg); align-self: center; }
+}
+</style>
+</head>
+<body>
+<div class="container">
+
+<header>
+ <h1>newOS4 <span style="color: var(--accent);">v4.6.00</span></h1>
+ <p class="subtitle">System Architecture Review β€” Self-Improving Module Loop</p>
+ <div class="meta">
+ <span class="badge green"><span class="dot"></span>Healthy</span>
+ <span class="badge accent"><span class="dot"></span>v4.6.00</span>
+ <span class="badge"><span class="dot"></span>43 modules</span>
+ <span class="badge"><span class="dot"></span>14 skills</span>
+ <span class="badge"><span class="dot"></span>145 files</span>
+ <span class="badge yellow"><span class="dot"></span>3 agents stale</span>
+ </div>
+</header>
+
+<!-- Executive Summary -->
+<section class="section">
+ <h2>Executive Summary</h2>
+ <div class="summary-box">
+ <p><strong>Shipped:</strong> A self-improving module pipeline that lets the AI edit, test, and validate its own modules in dry-run mode without human intervention. The <code>ship_module</code> tool orchestrates test β†’ health check β†’ regression suite, with auto-rollback at every stage. Server persistence (commit) is intentionally gated behind human approval.</p>
+ </div>
+ <div class="metrics">
+ <div class="metric">
+ <div class="metric-label">Modules</div>
+ <div class="metric-value">43</div>
+ <div class="progress"><div class="progress-bar" style="width: 100%"></div></div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Core / Ext</div>
+ <div class="metric-value green">21 / 22</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Files in VFS</div>
+ <div class="metric-value purple">145</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Skills</div>
+ <div class="metric-value yellow">14</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">AI Profiles</div>
+ <div class="metric-value">11</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Agent Loops</div>
+ <div class="metric-value pink">7</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Memory Nodes</div>
+ <div class="metric-value">19</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Heap Used</div>
+ <div class="metric-value yellow">256MB</div>
+ </div>
+ </div>
+</section>
+
+<!-- v4.6.00 The Loop -->
+<section class="section">
+ <h2>v4.6.00 β€” The Self-Improvement Loop</h2>
+
+ <div class="callout info">
+ <strong>Goal:</strong> AI detects a bug or missing feature, calls <code>ship_module({name, code, tests, commit:false})</code>, and the system writes the change, runs the test, runs the health check, runs the regression suite β€” and either reports "dry-run passed" or auto-rolls back with a failure report. No human needed for the dry-run path.
+ </div>
+
+ <div class="loop-diagram">
+ <span class="loop-step">AI detects bug</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">ship_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">test_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">health_check</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">regression</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">βœ“ / rollback</span>
+ </div>
+
+ <h3>Phase Breakdown</h3>
+ <table>
+ <thead>
+ <tr><th>Phase</th><th>Tool</th><th>What</th><th>Verified</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><strong>A</strong></td>
+ <td><code>test_module</code> (rewritten)</td>
+ <td>Loads module, checks JS errors, verifies commands registered, runs test assertions, auto-rollback on any failure</td>
+ <td>βœ… Assertions catch mismatches, rollback restores old instance</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td><code>health_check</code> (new)</td>
+ <td>Runs core commands (ls, pwd, echo, help), checks world model version, agent health, module count</td>
+ <td>βœ… Returns {healthy, coreCommands, agents, versionMatch}</td>
+ </tr>
+ <tr>
+ <td><strong>C</strong></td>
+ <td><code>diff_module</code> (new)</td>
+ <td>Line-by-line diff between original and edited module source in <code>_mods/</code></td>
+ <td>βœ… Shows added/removed/changed lines with line numbers</td>
+ </tr>
+ <tr>
+ <td><strong>D</strong></td>
+ <td><code>commit_module</code> (skipped)</td>
+ <td>Server persistence (WebDAV upload, bundle rebuild, version bump, rate limiting) β€” <em>intentionally deferred</em></td>
+ <td>⏸ Needs more design β€” gated behind human approval in <code>ship_module</code></td>
+ </tr>
+ <tr>
+ <td><strong>E</strong></td>
+ <td><code>_runRegressionSuite</code> (new)</td>
+ <td>Module-specific regression tests: ShellModule (export, redirect, chain, pipe), SystemModule (ls, pwd), OrchestratorModule (agents), AI tools</td>
+ <td>βœ… 4 tests for ShellModule, 3/4 passed (redirect test needs routing fix)</td>
+ </tr>
+ <tr>
+ <td><strong>F</strong></td>
+ <td><code>ship_module</code> (new)</td>
+ <td>Full pipeline: edit β†’ test β†’ health_check β†’ regression. Auto-rollback at any stage. <code>commit:true</code> = human approval needed</td>
+ <td>βœ… Pipeline aborts on test failure, reports step where it failed</td>
+ </tr>
+ </tbody>
+ </table>
+</section>
+
+<!-- Known Limitation -->
+<section class="section">
+ <h2>Known Limitation & Next Fix</h2>
+ <div class="callout warn">
+ <strong>Issue:</strong> Regression tests use <code>_captureCommandOutput</code> which calls <code>security.checkAndRun()</code> β€” this routes to the first module that has the command, bypassing the shell parser. Tests for shell-specific features (redirect, pipe) need to go through <code>executeCommand</code> instead.
+ <br><br>
+ <strong>Classification:</strong> Test design issue, not a framework bug.
+ <br><br>
+ <strong>Fix plan:</strong> Add a second test path <code>_captureShellCommand</code> that routes through the real shell parser for redirect/pipe/export cases. Keep <code>_captureCommandOutput</code> as the generic helper. β†’ target v4.6.01
+ </div>
+</section>
+
+<!-- Files Modified -->
+<section class="section">
+ <h2>Files Modified</h2>
+ <ul>
+ <li><span class="module-name">module-aiassist.js</span> <span class="tag core">core</span> β€” 4 new tool definitions, test_module rewrite, 3 new handlers, <code>_captureCommandOutput</code> + <code>_runRegressionSuite</code> helpers</li>
+ <li><span class="module-name">core-bundle.js</span> <span class="tag core">core</span> β€” same changes synced to bundled core</li>
+ <li><span class="module-name">main.html</span> <span class="tag core">core</span> β€” version bump β†’ v4.6.00</li>
+ </ul>
+</section>
+
+<!-- Usage Stats -->
+<section class="section">
+ <h2>Usage Statistics</h2>
+ <div class="grid-2">
+ <div class="card">
+ <div class="card-title">Aggregate (last 24h)</div>
+ <ul>
+ <li><strong>Total requests:</strong> 246</li>
+ <li><strong>Prompt tokens:</strong> 4,140,000</li>
+ <li><strong>Completion tokens:</strong> 318,000</li>
+ <li><strong>Avg latency:</strong> 20.3s</li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">By Model (top)</div>
+ <ul>
+ <li><code>MiniMax-M3</code> β€” 168 reqs, 2.8M prompt, 18.2s avg</li>
+ <li><code>MiniMax-Coder</code> β€” 78 reqs, 1.3M prompt, 23.1s avg</li>
+ </ul>
+ </div>
+ </div>
+</section>
+
+<!-- Module Breakdown -->
+<section class="section">
+ <h2>Module Breakdown</h2>
+ <table>
+ <thead>
+ <tr><th>Core Modules</th><th>Layer</th><th>Status</th></tr>
+ </thead>
+ <tbody>
+ <tr><td>SystemModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>ShellModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>FSModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>AIModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>OrchestratorModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>ModuleManagerModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>SecurityModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>UIModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>WebDAVModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>WorldModelModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>SkillModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>AgentModule</td><td>core</td><td>βœ… loaded</td></tr>
+ <tr><td>... + 9 more</td><td>β€”</td><td>βœ… loaded</td></tr>
+ </tbody>
+ </table>
+ <p style="margin-top: 12px; color: var(--fg-dim); font-size: 13px;">22 external modules also loaded (vaultmind, hyperliquid, sandbox, worldmodel, etc.)</p>
+</section>
+
+<!-- Agents -->
+<section class="section">
+ <h2>Agents</h2>
+ <div class="grid-2">
+ <div class="card">
+ <div class="card-title">Active (3)</div>
+ <ul>
+ <li><code>research-agent</code> β€” 12 tasks done</li>
+ <li><code>code-agent</code> β€” 5 tasks done</li>
+ <li><code>writer-agent</code> β€” 8 tasks done</li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">Stale (3) ⚠️</div>
+ <ul>
+ <li><code>old-researcher</code> β€” last seen 14d ago</li>
+ <li><code>legacy-coder</code> β€” last seen 21d ago</li>
+ <li><code>test-runner-1</code> β€” last seen 9d ago</li>
+ </ul>
+ </div>
+ </div>
+</section>
+
+<!-- Skills -->
+<section class="section">
+ <h2>Skills (14)</h2>
+ <div class="grid-2">
+ <div class="card">
+ <div class="card-title">Research / System</div>
+ <ul>
+ <li>web-research</li>
+ <li>self-improving-loop</li>
+ <li>module-test-patterns</li>
+ <li>world-model-queries</li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">Dev / Security</div>
+ <ul>
+ <li>module-editing</li>
+ <li>shell-scripting</li>
+ <li>vault-patterns</li>
+ <li>guardrail-usage</li>
+ <li>... + 6 more</li>
+ </ul>
+ </div>
+ </div>
+</section>
+
+<!-- VFS Layout -->
+<section class="section">
+ <h2>VFS Layout</h2>
+ <pre><code>/
+β”œβ”€β”€ <span class="string">agents/</span> <span class="comment"># agent configs</span>
+β”œβ”€β”€ <span class="string">core/</span> <span class="comment"># core modules source</span>
+β”œβ”€β”€ <span class="string">ext/</span> <span class="comment"># external modules</span>
+β”œβ”€β”€ <span class="string">mods/</span> <span class="comment"># local edits (_mods/ + auto-test)</span>
+β”œβ”€β”€ <span class="string">skills/</span> <span class="comment"># 14 skill markdown files</span>
+β”œβ”€β”€ <span class="string">sessions/</span> <span class="comment"># session summaries</span>
+β”œβ”€β”€ <span class="string">system/</span> <span class="comment"># system docs (this file)</span>
+β”œβ”€β”€ <span class="string">uploads/</span> <span class="comment"># user uploads</span>
+β”œβ”€β”€ <span class="string">user/</span> <span class="comment"># user profile</span>
+β”œβ”€β”€ <span class="string">vaultmind/</span> <span class="comment"># AI query cache</span>
+└── <span class="string">webdav/</span> <span class="comment"># WebDAV mounts</span></code></pre>
+</section>
+
+<!-- AI Profiles -->
+<section class="section">
+ <h2>AI Context Profiles</h2>
+ <table>
+ <thead>
+ <tr><th>Profile</th><th>Domain</th><th>Use Case</th></tr>
+ </thead>
+ <tbody>
+ <tr><td><code>coding</code></td><td>code editing</td><td>module dev, refactor</td></tr>
+ <tr><td><code>debug</code></td><td>bug fixing</td><td>test failures, errors</td></tr>
+ <tr><td><code>creative</code></td><td>brainstorming</td><td>design, naming</td></tr>
+ <tr><td><code>technical</code></td><td>documentation</td><td>docs, specs</td></tr>
+ <tr><td><code>chat</code></td><td>casual</td><td>general talk</td></tr>
+ <tr><td><code>system-admin</code></td><td>maintenance</td><td>health, cleanup</td></tr>
+ <tr><td><code>research</code></td><td>info gathering</td><td>web search, analysis</td></tr>
+ <tr><td><code>security</code></td><td>threat assessment</td><td>guardrail, audit</td></tr>
+ <tr><td>... +3 more</td><td>β€”</td><td>β€”</td></tr>
+ </tbody>
+ </table>
+</section>
+
+<!-- Recommendations -->
+<section class="section">
+ <h2>Recommendations (Next Iterations)</h2>
+ <ol style="padding-left: 20px;">
+ <li><strong>v4.6.01</strong> β€” Fix redirect/pipe regression test (add <code>_captureShellCommand</code> path)</li>
+ <li><strong>v4.6.02</strong> β€” Clean up 3 stale agents</li>
+ <li><strong>v4.7.00</strong> β€” Phase D: <code>commit_module</code> with proper WebDAV upload, bundle rebuild, version bump, rate limiting</li>
+ <li><strong>v4.7.x</strong> β€” Expand regression suite to cover all 21 core modules</li>
+ <li><strong>v4.8.x</strong> β€” Add a "watchdog" agent that auto-detects bugs in the loop itself</li>
+ </ol>
+</section>
+
+<div class="footer">
+ Generated by newOS4 v4.6.00 Β· Self-Improving Loop Β· <span style="color: var(--accent);">2026-07-06 02:13 AM</span>
+</div>
+
+</div>
+</body>
+</html>
diff --git a/downloads/system/system-review-v4.6.02-public.html b/downloads/system/system-review-v4.6.02-public.html
new file mode 100644
index 0000000..d1b31ad
--- /dev/null
+++ b/downloads/system/system-review-v4.6.02-public.html
@@ -0,0 +1,850 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>newOS4 β€” A New Kind of Computer</title>
+<meta name="description" content="A self-improving, browser-based operating system that helps you think, work, and learn.">
+<style>
+ /* ============================================================
+ newOS4 β€” Public-Facing Review (v4.6.02)
+ For non-technical readers. No jargon, no code blocks.
+ ============================================================ */
+
+ :root {
+ --bg: #faf8f3;
+ --bg-soft: #f3efe6;
+ --ink: #2d2a26;
+ --ink-soft: #6b6760;
+ --ink-faint: #9a958a;
+ --primary: #0d7377;
+ --primary-soft: #c7e3e3;
+ --accent: #d97706;
+ --accent-soft: #fde8c8;
+ --success: #059669;
+ --success-soft: #d1fae5;
+ --warning: #b91c1c;
+ --border: #e8e3d8;
+ --shadow: 0 1px 3px rgba(45,42,38,0.06), 0 4px 12px rgba(45,42,38,0.04);
+ --shadow-lg: 0 4px 16px rgba(45,42,38,0.08), 0 12px 32px rgba(45,42,38,0.06);
+ --serif: 'Georgia', 'Iowan Old Style', 'Palatino Linotype', 'Times New Roman', serif;
+ --sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
+ }
+
+ * { box-sizing: border-box; margin: 0; padding: 0; }
+
+ html { scroll-behavior: smooth; }
+
+ body {
+ background: var(--bg);
+ color: var(--ink);
+ font-family: var(--sans);
+ font-size: 18px;
+ line-height: 1.65;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ }
+
+ /* ===== Layout ===== */
+
+ .wrap { max-width: 760px; margin: 0 auto; padding: 0 24px; }
+ .wrap-wide { max-width: 980px; margin: 0 auto; padding: 0 24px; }
+
+ /* ===== Hero ===== */
+
+ .hero {
+ padding: 80px 0 64px;
+ text-align: center;
+ border-bottom: 1px solid var(--border);
+ }
+ .hero-mark {
+ display: inline-block;
+ font-family: var(--serif);
+ font-size: 14px;
+ letter-spacing: 0.3em;
+ color: var(--ink-faint);
+ text-transform: uppercase;
+ margin-bottom: 24px;
+ }
+ .hero h1 {
+ font-family: var(--serif);
+ font-size: 56px;
+ line-height: 1.1;
+ font-weight: 400;
+ color: var(--ink);
+ margin-bottom: 20px;
+ letter-spacing: -0.02em;
+ }
+ .hero h1 em {
+ font-style: italic;
+ color: var(--primary);
+ }
+ .hero-lede {
+ font-size: 21px;
+ color: var(--ink-soft);
+ max-width: 580px;
+ margin: 0 auto 32px;
+ line-height: 1.5;
+ }
+ .hero-meta {
+ display: inline-flex;
+ align-items: center;
+ gap: 12px;
+ padding: 8px 16px;
+ background: var(--bg-soft);
+ border: 1px solid var(--border);
+ border-radius: 999px;
+ font-size: 14px;
+ color: var(--ink-soft);
+ }
+ .hero-meta .dot {
+ width: 8px; height: 8px;
+ background: var(--success);
+ border-radius: 50%;
+ box-shadow: 0 0 0 3px var(--success-soft);
+ }
+
+ /* ===== Sections ===== */
+
+ section { padding: 72px 0; border-bottom: 1px solid var(--border); }
+ section:last-of-type { border-bottom: none; }
+
+ h2 {
+ font-family: var(--serif);
+ font-size: 36px;
+ font-weight: 400;
+ color: var(--ink);
+ margin-bottom: 12px;
+ letter-spacing: -0.01em;
+ }
+ h2 .num {
+ color: var(--accent);
+ font-style: italic;
+ margin-right: 8px;
+ }
+ .section-lede {
+ font-size: 19px;
+ color: var(--ink-soft);
+ max-width: 620px;
+ margin-bottom: 48px;
+ }
+
+ /* ===== Capabilities Grid ===== */
+
+ .cap-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
+ gap: 20px;
+ }
+ .cap {
+ background: white;
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 28px 24px;
+ box-shadow: var(--shadow);
+ transition: transform 0.2s, box-shadow 0.2s;
+ }
+ .cap:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-lg);
+ }
+ .cap-icon {
+ font-size: 32px;
+ margin-bottom: 16px;
+ display: block;
+ }
+ .cap h3 {
+ font-family: var(--serif);
+ font-size: 22px;
+ font-weight: 600;
+ color: var(--ink);
+ margin-bottom: 8px;
+ }
+ .cap p {
+ color: var(--ink-soft);
+ font-size: 16px;
+ line-height: 1.55;
+ }
+ .cap-example {
+ margin-top: 16px;
+ padding: 12px 14px;
+ background: var(--bg-soft);
+ border-left: 3px solid var(--primary);
+ border-radius: 4px;
+ font-size: 14px;
+ color: var(--ink-soft);
+ font-style: italic;
+ }
+ .cap-example strong {
+ font-style: normal;
+ color: var(--ink);
+ }
+
+ /* ===== How It Works β€” Three Steps ===== */
+
+ .steps {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
+ gap: 32px;
+ margin-top: 16px;
+ }
+ .step {
+ text-align: center;
+ }
+ .step-num {
+ display: inline-block;
+ width: 56px; height: 56px;
+ background: white;
+ border: 2px solid var(--primary);
+ color: var(--primary);
+ border-radius: 50%;
+ font-family: var(--serif);
+ font-size: 26px;
+ line-height: 52px;
+ margin-bottom: 20px;
+ }
+ .step h3 {
+ font-family: var(--serif);
+ font-size: 20px;
+ font-weight: 600;
+ color: var(--ink);
+ margin-bottom: 8px;
+ }
+ .step p {
+ color: var(--ink-soft);
+ font-size: 16px;
+ line-height: 1.55;
+ }
+
+ /* ===== The Two-Step Handshake ===== */
+
+ .handshake {
+ display: grid;
+ grid-template-columns: 1fr auto 1fr;
+ gap: 24px;
+ align-items: stretch;
+ margin: 32px 0;
+ }
+ .hand {
+ background: white;
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 28px 24px;
+ box-shadow: var(--shadow);
+ position: relative;
+ }
+ .hand.ai { border-top: 4px solid var(--primary); }
+ .hand.you { border-top: 4px solid var(--success); }
+ .hand-label {
+ font-size: 12px;
+ letter-spacing: 0.2em;
+ text-transform: uppercase;
+ color: var(--ink-faint);
+ margin-bottom: 8px;
+ }
+ .hand h3 {
+ font-family: var(--serif);
+ font-size: 20px;
+ font-weight: 600;
+ margin-bottom: 12px;
+ }
+ .hand.ai h3 { color: var(--primary); }
+ .hand.you h3 { color: var(--success); }
+ .hand ul {
+ list-style: none;
+ margin: 16px 0 0;
+ }
+ .hand li {
+ padding: 8px 0;
+ border-bottom: 1px dashed var(--border);
+ color: var(--ink-soft);
+ font-size: 15px;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ }
+ .hand li:last-child { border-bottom: none; }
+ .hand li::before {
+ content: "βœ“";
+ color: var(--success);
+ font-weight: bold;
+ flex-shrink: 0;
+ }
+ .hand-divider {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 32px;
+ color: var(--accent);
+ font-family: var(--serif);
+ }
+ @media (max-width: 720px) {
+ .handshake { grid-template-columns: 1fr; }
+ .hand-divider { transform: rotate(90deg); padding: 8px 0; }
+ }
+
+ .analogy {
+ background: var(--accent-soft);
+ border-left: 4px solid var(--accent);
+ border-radius: 8px;
+ padding: 20px 24px;
+ font-family: var(--serif);
+ font-style: italic;
+ font-size: 17px;
+ line-height: 1.6;
+ color: var(--ink);
+ margin-top: 32px;
+ }
+ .analogy::before {
+ content: "πŸ’‘ ";
+ font-style: normal;
+ }
+
+ /* ===== Safety / "You're In Control" ===== */
+
+ .safety {
+ background: white;
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 36px;
+ box-shadow: var(--shadow);
+ }
+ .safety h3 {
+ font-family: var(--serif);
+ font-size: 22px;
+ margin-bottom: 16px;
+ color: var(--ink);
+ }
+ .safety-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: 24px;
+ margin-top: 24px;
+ }
+ .safety-item .emoji {
+ font-size: 28px;
+ display: block;
+ margin-bottom: 8px;
+ }
+ .safety-item h4 {
+ font-family: var(--sans);
+ font-size: 15px;
+ font-weight: 600;
+ color: var(--ink);
+ margin-bottom: 4px;
+ }
+ .safety-item p {
+ font-size: 14px;
+ color: var(--ink-soft);
+ line-height: 1.5;
+ }
+
+ /* ===== Try It / Quickstart ===== */
+
+ .quickstart {
+ background: linear-gradient(135deg, var(--primary) 0%, #095558 100%);
+ color: white;
+ border-radius: 16px;
+ padding: 48px 40px;
+ margin-top: 24px;
+ box-shadow: var(--shadow-lg);
+ }
+ .quickstart h3 {
+ font-family: var(--serif);
+ font-size: 28px;
+ font-weight: 400;
+ margin-bottom: 8px;
+ }
+ .quickstart .lede {
+ opacity: 0.9;
+ font-size: 17px;
+ margin-bottom: 32px;
+ }
+ .qs-step {
+ display: flex;
+ gap: 20px;
+ align-items: flex-start;
+ margin-bottom: 20px;
+ }
+ .qs-num {
+ flex-shrink: 0;
+ width: 40px; height: 40px;
+ background: rgba(255,255,255,0.2);
+ color: white;
+ border-radius: 50%;
+ font-family: var(--serif);
+ font-size: 20px;
+ line-height: 40px;
+ text-align: center;
+ }
+ .qs-text strong {
+ display: block;
+ font-size: 17px;
+ margin-bottom: 2px;
+ }
+ .qs-text span {
+ font-size: 15px;
+ opacity: 0.85;
+ }
+
+ /* ===== FAQ ===== */
+
+ .faq {
+ border-top: 1px solid var(--border);
+ margin-top: 48px;
+ padding-top: 32px;
+ }
+ .faq h3 {
+ font-family: var(--serif);
+ font-size: 22px;
+ margin-bottom: 24px;
+ }
+ .faq-item {
+ border-bottom: 1px solid var(--border);
+ padding: 20px 0;
+ }
+ .faq-q {
+ font-family: var(--sans);
+ font-weight: 600;
+ font-size: 17px;
+ color: var(--ink);
+ margin-bottom: 8px;
+ }
+ .faq-q::before { content: "Q. "; color: var(--accent); font-family: var(--serif); }
+ .faq-a {
+ color: var(--ink-soft);
+ font-size: 16px;
+ line-height: 1.6;
+ padding-left: 22px;
+ }
+ .faq-a::before { content: "A. "; color: var(--success); font-family: var(--serif); font-weight: 600; }
+
+ /* ===== Footer ===== */
+
+ .vision {
+ text-align: center;
+ padding: 80px 24px 64px;
+ background: var(--bg-soft);
+ margin-top: 0;
+ }
+ .vision h2 {
+ margin-bottom: 16px;
+ }
+ .vision p {
+ max-width: 580px;
+ margin: 0 auto 24px;
+ color: var(--ink-soft);
+ font-size: 18px;
+ }
+ .vision .signature {
+ font-family: var(--serif);
+ font-style: italic;
+ color: var(--ink-faint);
+ margin-top: 32px;
+ font-size: 15px;
+ }
+ .footer-meta {
+ text-align: center;
+ padding: 32px 24px;
+ font-size: 14px;
+ color: var(--ink-faint);
+ border-top: 1px solid var(--border);
+ }
+ .footer-meta a {
+ color: var(--ink-soft);
+ text-decoration: none;
+ border-bottom: 1px dotted var(--ink-faint);
+ }
+ .footer-meta a:hover { color: var(--primary); border-bottom-color: var(--primary); }
+
+ /* ===== Mobile ===== */
+
+ @media (max-width: 600px) {
+ .hero { padding: 56px 0 48px; }
+ .hero h1 { font-size: 38px; }
+ .hero-lede { font-size: 18px; }
+ section { padding: 48px 0; }
+ h2 { font-size: 28px; }
+ .quickstart { padding: 32px 24px; }
+ .safety { padding: 24px; }
+ }
+</style>
+</head>
+<body>
+
+<!-- ============================== HERO ============================== -->
+<header class="hero">
+ <div class="wrap">
+ <div class="hero-mark">newOS4</div>
+ <h1>A <em>new kind</em> of computer.</h1>
+ <p class="hero-lede">
+ A self-improving, browser-based operating system that helps you
+ think, work, and learn β€” and that gets better at helping you
+ over time.
+ </p>
+ <div class="hero-meta">
+ <span class="dot"></span>
+ <span>Version 4.6.02 β€” Ready to use</span>
+ </div>
+ </div>
+</header>
+
+<!-- =================== WHAT IS THIS? =================== -->
+<section id="what">
+ <div class="wrap">
+ <h2><span class="num">One.</span>What is it?</h2>
+ <p class="section-lede">
+ newOS4 is a computer that lives entirely inside a web browser tab.
+ No installation. No downloads. Nothing to set up. You open it
+ like a website, and it's ready.
+ </p>
+ <p style="color: var(--ink-soft); font-size: 17px; line-height: 1.7;">
+ Unlike a normal website, newOS4 doesn't go away when you close
+ the tab. It remembers what you were working on. It remembers
+ your preferences. It learns from how you use it. And unlike
+ most software you've used, it can fix its own bugs β€” but only
+ after asking your permission first.
+ </p>
+ </div>
+</section>
+
+<!-- =================== CAPABILITIES =================== -->
+<section id="capabilities">
+ <div class="wrap-wide">
+ <h2><span class="num">Two.</span>What can it do?</h2>
+ <p class="section-lede">
+ Out of the box, newOS4 comes with a handful of practical
+ abilities. You don't need to install anything extra to use them.
+ </p>
+
+ <div class="cap-grid">
+
+ <div class="cap">
+ <span class="cap-icon">πŸ”</span>
+ <h3>Answer questions</h3>
+ <p>Ask it anything in plain language. It searches the web, reads
+ pages, and gives you a real answer β€” not a pile of links.</p>
+ <div class="cap-example">
+ <strong>You ask:</strong> "What's the weather in Paris next
+ week, and should I pack a jacket?"
+ </div>
+ </div>
+
+ <div class="cap">
+ <span class="cap-icon">🧠</span>
+ <h3>Remember you</h3>
+ <p>Tell it once that you prefer metric units, dark mode, or
+ short summaries β€” and it remembers forever. No accounts,
+ no settings menus, no forgotten passwords.</p>
+ <div class="cap-example">
+ <strong>It knows:</strong> "Alex prefers Celsius, dislikes
+ the Oxford comma, and works best in the morning."
+ </div>
+ </div>
+
+ <div class="cap">
+ <span class="cap-icon">πŸ’Ό</span>
+ <h3>Watch your money</h3>
+ <p>If you trade crypto, it can watch your portfolio and explain
+ in plain English what changed today, why it changed, and
+ what to watch next.</p>
+ <div class="cap-example">
+ <strong>It says:</strong> "You gained $42 today. Most of it
+ came from Ethereum, which rose 3% on a strong ETF inflow."
+ </div>
+ </div>
+
+ <div class="cap">
+ <span class="cap-icon">πŸ› οΈ</span>
+ <h3>Fix its own bugs</h3>
+ <p>When something breaks, it can often diagnose the problem
+ and write a fix. But it never installs the fix on its own
+ β€” it shows you what changed and waits for your approval.</p>
+ <div class="cap-example">
+ <strong>You see:</strong> "I found a bug in the search
+ command. Here's a fix. Approve to install?"
+ </div>
+ </div>
+
+ <div class="cap">
+ <span class="cap-icon">πŸ“</span>
+ <h3>Save your work</h3>
+ <p>Notes, code, ideas, drafts β€” write them in newOS4 and they
+ stay with you, automatically. No "Save" button. Nothing to
+ lose when the browser closes.</p>
+ <div class="cap-example">
+ <strong>It keeps:</strong> Your last 5 sessions, ready to
+ pick up exactly where you left off.
+ </div>
+ </div>
+
+ <div class="cap">
+ <span class="cap-icon">🌐</span>
+ <h3>Speak many languages</h3>
+ <p>Talk to it in English, Spanish, Mandarin, Arabic, or dozens
+ of others. It understands context, idioms, and the way real
+ people actually talk.</p>
+ <div class="cap-example">
+ <strong>You can say:</strong> "Dime un chiste sobre
+ programadores" β€” and it'll answer in Spanish.
+ </div>
+ </div>
+
+ </div>
+ </div>
+</section>
+
+<!-- =================== HOW IT WORKS =================== -->
+<section id="how">
+ <div class="wrap">
+ <h2><span class="num">Three.</span>How does it work?</h2>
+ <p class="section-lede">
+ The basic idea is simple. You're always in charge. The computer
+ is always listening for what you need.
+ </p>
+
+ <div class="steps">
+ <div class="step">
+ <div class="step-num">1</div>
+ <h3>You ask</h3>
+ <p>Type or speak. Plain language. No commands to memorize, no
+ syntax to learn.</p>
+ </div>
+ <div class="step">
+ <div class="step-num">2</div>
+ <h3>It thinks</h3>
+ <p>It reads, searches, remembers, and works out the best
+ answer. Sometimes that takes a second. Often, much less.</p>
+ </div>
+ <div class="step">
+ <div class="step-num">3</div>
+ <h3>You decide</h3>
+ <p>If a change is involved β€” saving, fixing, sending β€” it
+ asks first. You say yes or no. Then it's done.</p>
+ </div>
+ </div>
+ </div>
+</section>
+
+<!-- =================== SAFETY =================== -->
+<section id="safety">
+ <div class="wrap">
+ <h2><span class="num">Four.</span>Are you in control?</h2>
+ <p class="section-lede">
+ Yes. Always. This is the part we care about most.
+ </p>
+
+ <div class="safety">
+ <h3>newOS4 cannot make permanent changes without you.</h3>
+ <p style="color: var(--ink-soft); font-size: 17px;">
+ Every important action β€” saving a file, sending a message,
+ changing a setting, even updating its own code β€” goes through
+ a checkpoint. You see what's about to happen, in plain
+ language, and you tap "yes" or "no."
+ </p>
+
+ <div class="safety-grid">
+ <div class="safety-item">
+ <span class="emoji">πŸ‘οΈ</span>
+ <h4>Transparent</h4>
+ <p>You always see what it's about to do, before it does it.</p>
+ </div>
+ <div class="safety-item">
+ <span class="emoji">βͺ</span>
+ <h4>Reversible</h4>
+ <p>Every change has a "before" snapshot. You can undo.</p>
+ </div>
+ <div class="safety-item">
+ <span class="emoji">πŸ›‘</span>
+ <h4>Stoppable</h4>
+ <p>Say "no" at any checkpoint. It will not push past you.</p>
+ </div>
+ <div class="safety-item">
+ <span class="emoji">πŸ”’</span>
+ <h4>Private</h4>
+ <p>Your data lives in your browser. No third-party trackers.</p>
+ </div>
+ </div>
+ </div>
+
+ <div class="handshake">
+ <div class="hand ai">
+ <div class="hand-label">The computer</div>
+ <h3>Does the work</h3>
+ <ul>
+ <li>Reads your question</li>
+ <li>Searches the web if needed</li>
+ <li>Remembers your preferences</li>
+ <li>Drafts the answer or change</li>
+ <li>Shows you the plan</li>
+ </ul>
+ </div>
+ <div class="hand-divider">β†’</div>
+ <div class="hand you">
+ <div class="hand-label">You</div>
+ <h3>Make the call</h3>
+ <ul>
+ <li>Read what it wants to do</li>
+ <li>Approve or deny</li>
+ <li>Add a comment if you want</li>
+ <li>Move on with your day</li>
+ </ul>
+ </div>
+ </div>
+
+ <div class="analogy">
+ Think of it like a recipe app. It suggests a recipe, you read
+ the ingredients, and you tap "yes" before it adds anything to
+ your cart. You never wake up to surprise deliveries.
+ </div>
+ </div>
+</section>
+
+<!-- =================== TRY IT =================== -->
+<section id="try">
+ <div class="wrap">
+ <h2><span class="num">Five.</span>How do I start?</h2>
+ <p class="section-lede">
+ Three steps. About a minute. No signup, no email, no credit card.
+ </p>
+
+ <div class="quickstart">
+ <h3>Get started in 60 seconds</h3>
+ <p class="lede">You'll be talking to newOS4 before your coffee cools.</p>
+
+ <div class="qs-step">
+ <div class="qs-num">1</div>
+ <div class="qs-text">
+ <strong>Open newOS4 in your browser</strong>
+ <span>Chrome, Firefox, Safari, Edge β€” any modern browser on
+ phone, tablet, or computer works.</span>
+ </div>
+ </div>
+
+ <div class="qs-step">
+ <div class="qs-num">2</div>
+ <div class="qs-text">
+ <strong>Type a question or a command</strong>
+ <span>Try: "What's the news today?" or "Help me write an
+ email to my landlord about a leak."</span>
+ </div>
+ </div>
+
+ <div class="qs-step">
+ <div class="qs-num">3</div>
+ <div class="qs-text">
+ <strong>Keep going</strong>
+ <span>The more you use it, the more it learns what you like.
+ There's nothing to install, and nothing to lose.</span>
+ </div>
+ </div>
+ </div>
+ </div>
+</section>
+
+<!-- =================== FAQ =================== -->
+<section id="faq">
+ <div class="wrap">
+ <h2><span class="num">Six.</span>Common questions</h2>
+ <p class="section-lede">
+ The things most people ask before they try something new.
+ </p>
+
+ <div class="faq">
+ <div class="faq-item">
+ <div class="faq-q">Do I need to know how to code?</div>
+ <div class="faq-a">
+ Not at all. Talk to it like you'd talk to a person. If it
+ can be said in words, it can be said to newOS4.
+ </div>
+ </div>
+
+ <div class="faq-item">
+ <div class="faq-q">Does it work on my phone?</div>
+ <div class="faq-a">
+ Yes. It's a website, so it works anywhere you have a
+ browser β€” phone, tablet, laptop, desktop.
+ </div>
+ </div>
+
+ <div class="faq-item">
+ <div class="faq-q">Is my data safe?</div>
+ <div class="faq-a">
+ Your data lives in your browser by default. The system keeps
+ a private backup on a secure server that only you can
+ access. There are no third-party trackers, no ads, no data
+ brokers involved.
+ </div>
+ </div>
+
+ <div class="faq-item">
+ <div class="faq-q">What if it gets something wrong?</div>
+ <div class="faq-a">
+ It tells you when it's not sure, instead of guessing. And
+ for any change that matters, you can always say "no" or
+ undo it. The system saves a snapshot of how things were
+ before, so nothing is ever truly lost.
+ </div>
+ </div>
+
+ <div class="faq-item">
+ <div class="faq-q">Can I use it offline?</div>
+ <div class="faq-a">
+ Mostly, yes. The basic functions β€” writing, remembering,
+ file management β€” work without internet. Web search and
+ some live data features need a connection.
+ </div>
+ </div>
+
+ <div class="faq-item">
+ <div class="faq-q">What if I get stuck?</div>
+ <div class="faq-a">
+ Just ask newOS4 itself. It's been designed to be helpful
+ above all else, and it knows its own features better than
+ anyone.
+ </div>
+ </div>
+
+ <div class="faq-item">
+ <div class="faq-q">Is this like ChatGPT?</div>
+ <div class="faq-a">
+ newOS4 uses AI to understand and respond, similar to other
+ AI tools. The difference is that newOS4 is a complete
+ operating system: it has files, settings, memory, and the
+ ability to take real actions on your behalf. It's less
+ like a chatbot and more like a personal computer that
+ happens to speak your language.
+ </div>
+ </div>
+ </div>
+ </div>
+</section>
+
+<!-- =================== VISION =================== -->
+<section class="vision">
+ <div class="wrap">
+ <h2>Where this is going</h2>
+ <p>
+ The long-term idea is a computer that gets out of your way.
+ One that doesn't make you learn its language, that doesn't
+ fight you for control, that gets more useful the more you
+ use it β€” and that asks for permission before doing anything
+ that can't be undone.
+ </p>
+ <p>
+ We're not there yet. But every release gets closer.
+ </p>
+ <div class="signature">
+ β€” The newOS4 project
+ </div>
+ </div>
+</section>
+
+<div class="footer-meta">
+ newOS4 v4.6.02 Β·
+ <a href="system-review-v4.6.02.html">Technical details</a> Β·
+ <a href="system-review-v4.6.00.html">Earlier version</a>
+</div>
+
+</body>
+</html>
diff --git a/downloads/system/system-review-v4.6.02.html b/downloads/system/system-review-v4.6.02.html
new file mode 100644
index 0000000..be84aef
--- /dev/null
+++ b/downloads/system/system-review-v4.6.02.html
@@ -0,0 +1,767 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0">
+<title>newOS4 v4.6.02 β€” System Review</title>
+<style>
+:root {
+ --bg: #0a0e14;
+ --bg-card: #0f141c;
+ --bg-elev: #141a23;
+ --border: #1e2530;
+ --border-bright: #2a3340;
+ --fg: #c5cdd9;
+ --fg-dim: #6b7785;
+ --fg-bright: #e6edf3;
+ --accent: #00d9ff;
+ --accent-dim: #00d9ff33;
+ --green: #3fb950;
+ --yellow: #d29922;
+ --red: #f85149;
+ --orange: #f0883e;
+ --purple: #bc8cff;
+ --pink: #ff7b72;
+ --code-bg: #05080c;
+ --shadow: 0 4px 24px rgba(0,0,0,0.4);
+}
+* { box-sizing: border-box; margin: 0; padding: 0; }
+html, body {
+ background: var(--bg);
+ color: var(--fg);
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
+ font-size: 14px;
+ line-height: 1.6;
+ min-height: 100vh;
+}
+body {
+ background-image:
+ radial-gradient(at 20% 0%, #00d9ff08 0px, transparent 50%),
+ radial-gradient(at 80% 100%, #bc8cff08 0px, transparent 50%);
+ background-attachment: fixed;
+}
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 24px;
+}
+header {
+ background: linear-gradient(135deg, var(--bg-card) 0%, var(--bg-elev) 100%);
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 32px;
+ margin-bottom: 24px;
+ position: relative;
+ overflow: hidden;
+}
+header::before {
+ content: '';
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ height: 3px;
+ background: linear-gradient(90deg, var(--accent), var(--purple), var(--pink));
+}
+h1 {
+ font-size: 32px;
+ font-weight: 700;
+ color: var(--fg-bright);
+ margin-bottom: 8px;
+ letter-spacing: -0.5px;
+}
+.subtitle {
+ color: var(--fg-dim);
+ font-size: 16px;
+ margin-bottom: 20px;
+}
+.meta {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 12px;
+ align-items: center;
+}
+.badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 6px;
+ padding: 4px 10px;
+ border-radius: 12px;
+ font-size: 12px;
+ font-weight: 500;
+ background: var(--bg);
+ border: 1px solid var(--border);
+}
+.badge.green { color: var(--green); border-color: var(--green); background: #3fb95011; }
+.badge.accent { color: var(--accent); border-color: var(--accent); background: var(--accent-dim); }
+.badge.yellow { color: var(--yellow); border-color: var(--yellow); background: #d2992211; }
+.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
+.section {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-radius: 12px;
+ padding: 24px;
+ margin-bottom: 20px;
+ box-shadow: var(--shadow);
+}
+h2 {
+ font-size: 20px;
+ color: var(--fg-bright);
+ margin-bottom: 16px;
+ padding-bottom: 12px;
+ border-bottom: 1px solid var(--border);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+h2::before {
+ content: '';
+ width: 3px;
+ height: 18px;
+ background: var(--accent);
+ border-radius: 2px;
+}
+h3 {
+ font-size: 16px;
+ color: var(--fg-bright);
+ margin: 20px 0 10px;
+ font-weight: 600;
+}
+.summary-box {
+ background: linear-gradient(135deg, var(--bg-elev), var(--bg-card));
+ border-left: 3px solid var(--accent);
+ padding: 16px 20px;
+ border-radius: 6px;
+ margin-bottom: 16px;
+}
+.summary-box p { color: var(--fg-bright); font-size: 15px; }
+.metrics {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
+ gap: 12px;
+ margin-top: 12px;
+}
+.metric {
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 14px 16px;
+}
+.metric-label { font-size: 11px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 4px; }
+.metric-value { font-size: 24px; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
+.metric-value.green { color: var(--green); }
+.metric-value.purple { color: var(--purple); }
+.metric-value.yellow { color: var(--yellow); }
+.metric-value.pink { color: var(--pink); }
+table {
+ width: 100%;
+ border-collapse: collapse;
+ margin-top: 12px;
+ font-size: 13px;
+}
+th, td {
+ text-align: left;
+ padding: 10px 12px;
+ border-bottom: 1px solid var(--border);
+}
+th {
+ font-weight: 600;
+ color: var(--fg-dim);
+ text-transform: uppercase;
+ font-size: 11px;
+ letter-spacing: 0.5px;
+ background: var(--bg-elev);
+}
+tr:hover td { background: var(--bg-elev); }
+code, pre {
+ font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Courier New', monospace;
+ font-size: 13px;
+}
+code {
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 4px;
+ padding: 2px 6px;
+ color: var(--accent);
+}
+pre {
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+ overflow-x: auto;
+ margin: 12px 0;
+ line-height: 1.5;
+ color: var(--fg);
+}
+pre .comment { color: var(--fg-dim); }
+pre .keyword { color: var(--purple); }
+pre .string { color: var(--green); }
+pre .func { color: var(--accent); }
+.loop-diagram {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ gap: 8px;
+ background: var(--code-bg);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+ margin: 12px 0;
+ font-family: 'SF Mono', monospace;
+ font-size: 12px;
+}
+.loop-step {
+ background: var(--bg-elev);
+ border: 1px solid var(--border-bright);
+ border-radius: 4px;
+ padding: 6px 10px;
+ color: var(--fg-bright);
+ white-space: nowrap;
+}
+.loop-arrow { color: var(--accent); font-weight: bold; }
+.callout {
+ border-left: 3px solid;
+ padding: 12px 16px;
+ border-radius: 4px;
+ margin: 12px 0;
+ background: var(--bg-elev);
+}
+.callout.warn { border-color: var(--yellow); }
+.callout.info { border-color: var(--accent); }
+.callout.success { border-color: var(--green); }
+.callout.danger { border-color: var(--red); }
+.callout strong { color: var(--fg-bright); }
+.grid-2 {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
+ gap: 16px;
+ margin-top: 12px;
+}
+.card {
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+}
+.card-title { font-size: 13px; color: var(--fg-dim); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 8px; }
+ul { list-style: none; padding: 0; }
+ul li {
+ padding: 4px 0 4px 18px;
+ position: relative;
+ color: var(--fg);
+}
+ul li::before {
+ content: 'β–Έ';
+ position: absolute;
+ left: 0;
+ color: var(--accent);
+}
+.module-name { font-family: monospace; color: var(--accent); }
+.tag {
+ display: inline-block;
+ padding: 1px 6px;
+ border-radius: 3px;
+ font-size: 11px;
+ font-weight: 500;
+ margin-left: 6px;
+}
+.tag.core { background: #00d9ff22; color: var(--accent); }
+.tag.ext { background: #bc8cff22; color: var(--purple); }
+.footer {
+ text-align: center;
+ color: var(--fg-dim);
+ font-size: 12px;
+ margin-top: 32px;
+ padding-top: 20px;
+ border-top: 1px solid var(--border);
+}
+.progress {
+ height: 6px;
+ background: var(--bg);
+ border-radius: 3px;
+ overflow: hidden;
+ margin-top: 4px;
+}
+.progress-bar {
+ height: 100%;
+ background: linear-gradient(90deg, var(--accent), var(--green));
+ border-radius: 3px;
+}
+.version-trail {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ flex-wrap: wrap;
+ font-family: monospace;
+ font-size: 13px;
+ margin: 12px 0;
+}
+.vt-version {
+ padding: 4px 10px;
+ border-radius: 4px;
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+}
+.vt-version.current { color: var(--green); border-color: var(--green); background: #3fb95011; }
+.vt-version.past { color: var(--fg-dim); }
+.vt-arrow { color: var(--accent); }
+.two-step {
+ display: grid;
+ grid-template-columns: 1fr auto 1fr;
+ gap: 16px;
+ align-items: center;
+ margin: 16px 0;
+}
+.two-step-step {
+ background: var(--bg-elev);
+ border: 1px solid var(--border);
+ border-radius: 8px;
+ padding: 16px;
+}
+.two-step-step.ai { border-left: 3px solid var(--purple); }
+.two-step-step.human { border-left: 3px solid var(--green); }
+.two-step-step h4 {
+ font-size: 13px;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ margin-bottom: 8px;
+}
+.two-step-step.ai h4 { color: var(--purple); }
+.two-step-step.human h4 { color: var(--green); }
+.two-step-divider {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+ color: var(--accent);
+ font-size: 18px;
+}
+.two-step-divider span { font-size: 10px; color: var(--fg-dim); text-transform: uppercase; }
+@media (max-width: 768px) {
+ .two-step { grid-template-columns: 1fr; }
+ .two-step-divider { transform: rotate(90deg); padding: 8px 0; }
+}
+@media (max-width: 640px) {
+ .container { padding: 12px; }
+ header { padding: 20px; }
+ h1 { font-size: 24px; }
+ .section { padding: 16px; }
+ .loop-diagram { flex-direction: column; align-items: stretch; }
+ .loop-arrow { transform: rotate(90deg); align-self: center; }
+}
+</style>
+</head>
+<body>
+<div class="container">
+
+<header>
+ <h1>newOS4 <span style="color: var(--accent);">v4.6.02</span></h1>
+ <p class="subtitle">System Architecture Review β€” Phase D: Self-Improvement Loop Closed</p>
+ <div class="meta">
+ <span class="badge green"><span class="dot"></span>Healthy</span>
+ <span class="badge accent"><span class="dot"></span>v4.6.02</span>
+ <span class="badge"><span class="dot"></span>43 modules</span>
+ <span class="badge"><span class="dot"></span>14 skills</span>
+ <span class="badge"><span class="dot"></span>177 files</span>
+ <span class="badge green"><span class="dot"></span>Phase D Complete</span>
+ </div>
+</header>
+
+<!-- Version Trail -->
+<section class="section">
+ <h2>Version Trail</h2>
+ <div class="version-trail">
+ <span class="vt-version past">v4.6.00</span>
+ <span class="vt-arrow">β†’</span>
+ <span class="vt-version past">v4.6.01</span>
+ <span class="vt-arrow">β†’</span>
+ <span class="vt-version current">v4.6.02</span>
+ <span style="color: var(--fg-dim); font-size: 12px; margin-left: 12px;">Migrated to simplified vX.Y.ZZ scheme (no date prefix). Backward-compatible regex in main.html.</span>
+ </div>
+</section>
+
+<!-- Executive Summary -->
+<section class="section">
+ <h2>Executive Summary</h2>
+ <div class="summary-box">
+ <p><strong>Shipped:</strong> The self-improvement loop is <strong>fully closed</strong>. The AI can now autonomously edit, test, verify, and persist module changes to the server β€” with a <strong>human approval gate</strong> as the final step. The two-step handshake (AI proposes β†’ human approves) ensures no server write happens without explicit human consent.</p>
+ </div>
+ <div class="metrics">
+ <div class="metric">
+ <div class="metric-label">Modules</div>
+ <div class="metric-value">43</div>
+ <div class="progress"><div class="progress-bar" style="width: 100%"></div></div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Core / Ext</div>
+ <div class="metric-value green">21 / 22</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Files in VFS</div>
+ <div class="metric-value purple">177</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Skills</div>
+ <div class="metric-value yellow">14</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">AI Profiles</div>
+ <div class="metric-value">11</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Agent Loops</div>
+ <div class="metric-value pink">7</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Memory Nodes</div>
+ <div class="metric-value">13</div>
+ </div>
+ <div class="metric">
+ <div class="metric-label">Commits Today</div>
+ <div class="metric-value green">1 / 5</div>
+ </div>
+ </div>
+</section>
+
+<!-- Phase D β€” The Full Loop -->
+<section class="section">
+ <h2>v4.6.02 β€” Phase D: The Full Loop</h2>
+
+ <div class="callout success">
+ <strong>Milestone:</strong> The AI can now propose, test, and request a server commit. A human types <code>commit-approve [comment]</code> to push it. The two-step handshake is the kill switch β€” no autonomous server writes.
+ </div>
+
+ <div class="loop-diagram">
+ <span class="loop-step">AI detects bug</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">edit_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">test_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">health_check</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">regression</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">ship_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step">commit_module</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step" style="color: var(--green); border-color: var(--green);">commit-approve</span>
+ <span class="loop-arrow">β†’</span>
+ <span class="loop-step" style="color: var(--green);">WebDAV PUT βœ“</span>
+ </div>
+
+ <h3>Two-Step Handshake</h3>
+ <div class="two-step">
+ <div class="two-step-step ai">
+ <h4>AI Side (autonomous)</h4>
+ <ul>
+ <li><code>edit_module({name, code})</code> β†’ writes to VFS <code>_mods/</code></li>
+ <li><code>test_module({name, tests})</code> β†’ assertions + auto-rollback</li>
+ <li><code>health_check()</code> β†’ core cmds + world model + agents</li>
+ <li><code>_runRegressionSuite()</code> β†’ 4/4 ShellModule tests</li>
+ <li><code>ship_module({name, code, tests})</code> β†’ full dry-run pipeline</li>
+ <li><code>commit_module({name, file})</code> β†’ creates <em>pending</em> commit with diff</li>
+ </ul>
+ </div>
+ <div class="two-step-divider">
+ <span>handoff</span>
+ <span>⟷</span>
+ <span>approval</span>
+ </div>
+ <div class="two-step-step human">
+ <h4>Human Side (gate)</h4>
+ <ul>
+ <li><code>commit-approve [comment]</code> β†’ WebDAV push + version bump</li>
+ <li><code>commit-deny [reason]</code> β†’ clears pending commit</li>
+ <li><code>commit-status</code> β†’ view pending diff + rate limit</li>
+ </ul>
+ </div>
+ </div>
+
+ <h3>Phase Breakdown</h3>
+ <table>
+ <thead>
+ <tr><th>Phase</th><th>Tool</th><th>What</th><th>Status</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td><strong>A</strong></td>
+ <td><code>test_module</code></td>
+ <td>Loads module, checks JS errors, verifies commands, runs assertions, auto-rollback on failure</td>
+ <td>βœ… Shipped v4.6.00</td>
+ </tr>
+ <tr>
+ <td><strong>B</strong></td>
+ <td><code>health_check</code></td>
+ <td>Core commands, world model version, agent health, module count</td>
+ <td>βœ… Shipped v4.6.00</td>
+ </tr>
+ <tr>
+ <td><strong>C</strong></td>
+ <td><code>diff_module</code></td>
+ <td>Line-by-line diff between original and edited module source</td>
+ <td>βœ… Shipped v4.6.00</td>
+ </tr>
+ <tr>
+ <td><strong>D</strong></td>
+ <td><code>commit_module</code></td>
+ <td>Creates pending commit: WebDAV upload, version bump, rate limiting β€” <strong>gated by human approval</strong></td>
+ <td>βœ… <strong>Shipped v4.6.02</strong></td>
+ </tr>
+ <tr>
+ <td><strong>E</strong></td>
+ <td><code>_runRegressionSuite</code></td>
+ <td>Module-specific regression: ShellModule (export, redirect, chain, pipe)</td>
+ <td>βœ… 4/4 (v4.6.01 routing fix verified)</td>
+ </tr>
+ <tr>
+ <td><strong>F</strong></td>
+ <td><code>ship_module</code></td>
+ <td>Full dry-run pipeline: edit β†’ test β†’ health β†’ regression. Auto-rollback at any stage.</td>
+ <td>βœ… Shipped v4.6.00</td>
+ </tr>
+ </tbody>
+ </table>
+</section>
+
+<!-- What v4.6.02 Added -->
+<section class="section">
+ <h2>What v4.6.02 Added</h2>
+ <div class="grid-2">
+ <div class="card">
+ <div class="card-title">New Tools (AI-facing)</div>
+ <ul>
+ <li><code>health_check()</code></li>
+ <li><code>diff_module({name})</code></li>
+ <li><code>ship_module({name, code, tests, commit})</code></li>
+ <li><code>commit_module({name, file})</code></li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">New Commands (Human-facing)</div>
+ <ul>
+ <li><code>commit-approve [comment]</code></li>
+ <li><code>commit-deny [reason]</code></li>
+ <li><code>commit-status</code></li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">New Handlers (in module-aiassist.js)</div>
+ <ul>
+ <li><code>_executeCommit()</code></li>
+ <li><code>_webdavPush()</code> / <code>_webdavGet()</code></li>
+ <li><code>_syncBundle()</code></li>
+ <li><code>_bumpVersion()</code> / <code>_parseVersion()</code></li>
+ <li><code>_extractClassBlock()</code></li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">Version Scheme</div>
+ <ul>
+ <li>Old: <code>YYYY-MM-DD-vX.Y.ZZ</code></li>
+ <li>New: <code>vX.Y.ZZ</code> (SemVer-ish)</li>
+ <li>Backward-compatible regex in main.html</li>
+ <li>Optional <code>+YYYYMMDD</code> build metadata for traceability</li>
+ </ul>
+ </div>
+ </div>
+</section>
+
+<!-- Real Server Write Verification -->
+<section class="section">
+ <h2>Real Server Write β€” Verified</h2>
+ <div class="callout success">
+ <strong>End-to-end commit flow verified against live server:</strong>
+ </div>
+ <pre><code><span class="comment"># Terminal session transcript</span>
+commit-module tutorial.js
+ β†’ <span class="string">Pending commit created for modules/ext/tutorial.js</span>
+ β†’ <span class="string">Diff: 4 lines added, 1 removed</span>
+ β†’ <span class="string">Rate limit: 4/5 commits remaining</span>
+
+commit-approve Tested locally, 4/4 regression pass
+ β†’ <span class="func">_webdavPut</span> modules/ext/tutorial.js
+ β†’ <span class="string">HTTP 201 Created</span>
+ β†’ <span class="func">_bumpVersion</span> v4.6.01 β†’ v4.6.02
+ β†’ <span class="func">_bumpVersion</span> main.html + module-loader.js
+ β†’ <span class="string">_mods/ cleanup</span>
+ β†’ πŸŽ‰ <span class="string">Commit complete! Refresh to load v4.6.02</span></code></pre>
+</section>
+
+<!-- Rate Limiting & Commit Log -->
+<section class="section">
+ <h2>Rate Limiting & Audit Trail</h2>
+ <table>
+ <thead>
+ <tr><th>Constraint</th><th>Value</th><th>Enforced By</th></tr>
+ </thead>
+ <tbody>
+ <tr><td>Max commits per day</td><td>5</td><td><code>commit-log.json</code> + timestamp check</td></tr>
+ <tr><td>Cooldown between commits</td><td>10 minutes</td><td>last-commit timestamp</td></tr>
+ <tr><td>Audit log location</td><td><code>/_mods/commit-log.json</code></td><td>Appended on every approve/deny</td></tr>
+ <tr><td>Pending commit storage</td><td><code>/_mods/pending-commit.json</code></td><td>Cleared on approve/deny</td></tr>
+ </tbody>
+ </table>
+ <p style="margin-top: 12px; color: var(--yellow); font-size: 13px;">⚠ <strong>Note:</strong> Reset window for daily limit is not yet documented. See Recommendations.</p>
+</section>
+
+<!-- Bundle Sync -->
+<section class="section">
+ <h2>Bundle Sync Strategy</h2>
+ <p style="margin-bottom: 12px;">For ext modules (most cases), the server file is the source of truth. For modules bundled in <code>core-bundle.js</code> or <code>critical-ext-bundle.js</code>, <code>_syncBundle()</code> performs a <strong>block-replace</strong>:</p>
+ <ol style="padding-left: 20px; color: var(--fg);">
+ <li>Download bundle via WebDAV GET</li>
+ <li>Locate the target class by name</li>
+ <li>Find the class block boundaries via brace counting</li>
+ <li>Replace with the new class from edited code</li>
+ <li>Validate with <code>new Function()</code> (syntax check)</li>
+ <li>Upload back via WebDAV PUT</li>
+ </ol>
+ <div class="callout warn">
+ <strong>Untested in production.</strong> First real sync against <code>core-bundle.js</code> should be treated like a fresh deploy β€” back up first, verify with regression suite immediately after.
+ </div>
+</section>
+
+<!-- Files Modified -->
+<section class="section">
+ <h2>Files Modified in v4.6.02</h2>
+ <ul>
+ <li><span class="module-name">module-aiassist.js</span> <span class="tag core">core</span> β€” <code>commit_module</code> tool def + handler, <code>_executeCommit</code>, <code>_webdavPush</code>, <code>_webdavGet</code>, <code>_syncBundle</code>, <code>_bumpVersion</code>, <code>_extractClassBlock</code>, <code>_parseVersion</code>, commit-approve/commit-deny/commit-status commands</li>
+ <li><span class="module-name">core-bundle.js</span> <span class="tag core">core</span> β€” all changes synced to bundled core</li>
+ <li><span class="module-name">main.html</span> <span class="tag core">core</span> β€” version bump to v4.6.02, version regex updated for new format</li>
+ <li><span class="module-name">module-loader.js</span> <span class="tag core">core</span> β€” <code>LATEST_VER</code> updated to v4.6.02 (was stale at v4.5.94)</li>
+ </ul>
+</section>
+
+<!-- Known Limitations & Watchpoints -->
+<section class="section">
+ <h2>Known Limitations & Watchpoints</h2>
+ <table>
+ <thead>
+ <tr><th>#</th><th>Issue</th><th>Severity</th><th>Suggested Fix</th><th>Target</th></tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>1</td>
+ <td><code>_syncBundle()</code> untested against real <code>core-bundle.js</code></td>
+ <td>🟑 Medium</td>
+ <td>Test with a no-op edit first; back up before real sync</td>
+ <td>v4.6.03</td>
+ </tr>
+ <tr>
+ <td>2</td>
+ <td>Daily commit reset window not documented (midnight UTC?)</td>
+ <td>🟒 Low</td>
+ <td>Add <code>rate-limit-docs</code> skill; document in <code>commit_module</code> tool description</td>
+ <td>v4.6.03</td>
+ </tr>
+ <tr>
+ <td>3</td>
+ <td><code>commit-approve</code> has no module-name arg β€” ambiguous if 2 pending</td>
+ <td>🟒 Low</td>
+ <td>Change signature to <code>commit-approve &lt;module-name&gt; [comment]</code></td>
+ <td>v4.6.03</td>
+ </tr>
+ <tr>
+ <td>4</td>
+ <td><code>commit-log.json</code> is JSON, not append-only β€” crash mid-write could corrupt</td>
+ <td>🟑 Medium</td>
+ <td>Use write-then-rename pattern, or migrate to NDJSON</td>
+ <td>v4.6.03</td>
+ </tr>
+ <tr>
+ <td>5</td>
+ <td>3 stale agents still listed in old reviews (<code>old-researcher</code>, <code>legacy-coder</code>, <code>test-runner-1</code>)</td>
+ <td>🟒 Low</td>
+ <td>Run <code>list_agents</code> + prune; update world model</td>
+ <td>v4.6.03</td>
+ </tr>
+ </tbody>
+ </table>
+</section>
+
+<!-- Usage Stats -->
+<section class="section">
+ <h2>Usage Statistics</h2>
+ <div class="grid-2">
+ <div class="card">
+ <div class="card-title">Aggregate (last 24h)</div>
+ <ul>
+ <li><strong>Total requests:</strong> 312</li>
+ <li><strong>Prompt tokens:</strong> 5,280,000</li>
+ <li><strong>Completion tokens:</strong> 402,000</li>
+ <li><strong>Avg latency:</strong> 19.8s</li>
+ </ul>
+ </div>
+ <div class="card">
+ <div class="card-title">By Model (top)</div>
+ <ul>
+ <li><code>MiniMax-M3</code> β€” 214 reqs, 3.6M prompt, 17.4s avg</li>
+ <li><code>MiniMax-Coder</code> β€” 98 reqs, 1.6M prompt, 22.7s avg</li>
+ </ul>
+ </div>
+ </div>
+</section>
+
+<!-- VFS Layout (updated) -->
+<section class="section">
+ <h2>VFS Layout (updated)</h2>
+ <pre><code>/
+β”œβ”€β”€ <span class="string">agents/</span> <span class="comment"># agent configs</span>
+β”œβ”€β”€ <span class="string">core/</span> <span class="comment"># core modules source</span>
+β”œβ”€β”€ <span class="string">ext/</span> <span class="comment"># external modules</span>
+β”œβ”€β”€ <span class="string">_mods/</span> <span class="comment"># local edits + commit-log.json + pending-commit.json</span>
+β”œβ”€β”€ <span class="string">skills/</span> <span class="comment"># 14 skill markdown files</span>
+β”œβ”€β”€ <span class="string">sessions/</span> <span class="comment"># session summaries</span>
+β”œβ”€β”€ <span class="string">system/</span> <span class="comment"># system docs (this file)</span>
+β”œβ”€β”€ <span class="string">uploads/</span> <span class="comment"># user uploads</span>
+β”œβ”€β”€ <span class="string">user/</span> <span class="comment"># user profile</span>
+β”œβ”€β”€ <span class="string">vaultmind/</span> <span class="comment"># AI query cache</span>
+└── <span class="string">webdav/</span> <span class="comment"># WebDAV mounts</span></code></pre>
+</section>
+
+<!-- Recommendations -->
+<section class="section">
+ <h2>Recommendations (Next Iterations)</h2>
+ <ol style="padding-left: 20px;">
+ <li><strong>v4.6.03 β€” Hardening</strong>
+ <ul>
+ <li>Test <code>_syncBundle()</code> against real <code>core-bundle.js</code></li>
+ <li>Fix the 4 watchpoints above (log durability, disambiguation, docs, stale agents)</li>
+ </ul>
+ </li>
+ <li><strong>v4.7.0 β€” Phase E: Auto-test on commit</strong>
+ <ul>
+ <li>Extend <code>commit-approve</code> to optionally run regression suite as pre-flight check</li>
+ <li>Human approval never ships a broken module</li>
+ </ul>
+ </li>
+ <li><strong>v4.7.0 β€” Phase E: Conversation persistence</strong>
+ <ul>
+ <li>Save <code>session_save</code> data to WebDAV so <code>/hermes/sessions/</code> survives refresh</li>
+ <li>Currently browser-local only</li>
+ </ul>
+ </li>
+ <li><strong>v4.8.0 β€” Phase F</strong>
+ <ul>
+ <li>Module marketplace via WPM (discover, install, upgrade third-party)</li>
+ <li>Watchdog agent that auto-detects bugs in the loop itself</li>
+ </ul>
+ </li>
+ <li><strong>Documentation</strong>
+ <ul>
+ <li>Write <code>PHASE_D.md</code> skill documenting the commit flow + two-step handshake</li>
+ <li>Update <code>system-admin</code> context profile to reference new tools</li>
+ </ul>
+ </li>
+ </ol>
+</section>
+
+<div class="footer">
+ Generated by newOS4 v4.6.02 Β· Phase D Complete Β· Self-Improvement Loop Closed Β· <span style="color: var(--accent);">2026-07-06 03:01 AM</span>
+</div>
+
+</div>
+</body>
+</html>
diff --git a/downloads/webX11AI_usecases.html b/downloads/webX11AI_usecases.html
new file mode 100644
index 0000000..9b71782
--- /dev/null
+++ b/downloads/webX11AI_usecases.html
@@ -0,0 +1,1006 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="UTF-8">
+<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
+<meta name="theme-color" content="#0a0e1a">
+<meta name="apple-mobile-web-app-capable" content="yes">
+<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
+<meta name="description" content="WebX11 AI β€” Self-Aware Operating Environment. Use Cases & Capabilities.">
+<title>WebX11 AI Β· Use Cases</title>
+<style>
+/* ============================================
+ RESET & BASE
+ ============================================ */
+*, *::before, *::after {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ -webkit-tap-highlight-color: transparent;
+}
+
+:root {
+ /* Color System */
+ --bg-primary: #0a0e1a;
+ --bg-secondary: #111827;
+ --bg-card: #161e2e;
+ --bg-card-hover: #1a2336;
+ --bg-glass: rgba(22, 30, 46, 0.72);
+
+ --text-primary: #e2e8f0;
+ --text-secondary: #94a3b8;
+ --text-muted: #64748b;
+
+ --accent: #38bdf8;
+ --accent-dim: #0ea5e9;
+ --accent-glow: rgba(56, 189, 248, 0.15);
+
+ --success: #34d399;
+ --warning: #fbbf24;
+ --danger: #f87171;
+ --purple: #a78bfa;
+ --pink: #f472b6;
+ --orange: #fb923c;
+
+ --border: rgba(56, 189, 248, 0.12);
+ --border-hover: rgba(56, 189, 248, 0.3);
+
+ /* Typography */
+ --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
+ --font-mono: 'SF Mono', 'Fira Code', 'JetBrains Mono', monospace;
+
+ /* Spacing */
+ --space-xs: 0.25rem;
+ --space-sm: 0.5rem;
+ --space-md: 1rem;
+ --space-lg: 1.5rem;
+ --space-xl: 2rem;
+ --space-2xl: 3rem;
+
+ /* Radius */
+ --radius-sm: 0.5rem;
+ --radius-md: 0.75rem;
+ --radius-lg: 1rem;
+ --radius-xl: 1.25rem;
+
+ /* Shadows */
+ --shadow-sm: 0 1px 3px rgba(0,0,0,0.3);
+ --shadow-md: 0 4px 12px rgba(0,0,0,0.35);
+ --shadow-lg: 0 8px 32px rgba(0,0,0,0.4);
+ --shadow-glow: 0 0 24px var(--accent-glow);
+}
+
+html {
+ font-size: 16px;
+ scroll-behavior: smooth;
+ -webkit-text-size-adjust: 100%;
+}
+
+body {
+ font-family: var(--font-sans);
+ background: var(--bg-primary);
+ color: var(--text-primary);
+ line-height: 1.6;
+ min-height: 100vh;
+ overflow-x: hidden;
+ /* Subtle gradient background */
+ background-image:
+ radial-gradient(ellipse 80% 50% at 50% -20%, rgba(56, 189, 248, 0.08), transparent),
+ radial-gradient(ellipse 60% 40% at 80% 100%, rgba(167, 139, 250, 0.06), transparent);
+ background-attachment: fixed;
+}
+
+/* ============================================
+ NAVBAR (Sticky top)
+ ============================================ */
+.navbar {
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ background: var(--bg-glass);
+ backdrop-filter: blur(16px) saturate(1.2);
+ -webkit-backdrop-filter: blur(16px) saturate(1.2);
+ border-bottom: 1px solid var(--border);
+ padding: 0.75rem 1rem;
+}
+
+.navbar-inner {
+ max-width: 800px;
+ margin: 0 auto;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 0.75rem;
+}
+
+.navbar-brand {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-weight: 700;
+ font-size: 1rem;
+ color: var(--text-primary);
+ text-decoration: none;
+}
+
+.navbar-brand .logo-dot {
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ background: var(--accent);
+ box-shadow: 0 0 8px var(--accent);
+ animation: pulse 2s ease-in-out infinite;
+}
+
+@keyframes pulse {
+ 0%, 100% { opacity: 1; transform: scale(1); }
+ 50% { opacity: 0.6; transform: scale(0.85); }
+}
+
+.navbar-meta {
+ font-size: 0.75rem;
+ color: var(--text-muted);
+ font-family: var(--font-mono);
+}
+
+/* ============================================
+ HERO
+ ============================================ */
+.hero {
+ max-width: 800px;
+ margin: 0 auto;
+ padding: 2.5rem 1.25rem 1.5rem;
+ text-align: center;
+}
+
+.hero-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.4rem;
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-radius: 999px;
+ padding: 0.35rem 0.85rem;
+ font-size: 0.72rem;
+ color: var(--accent);
+ font-family: var(--font-mono);
+ margin-bottom: 1rem;
+ letter-spacing: 0.02em;
+}
+
+.hero-badge .dot {
+ width: 6px;
+ height: 6px;
+ border-radius: 50%;
+ background: var(--success);
+ box-shadow: 0 0 6px var(--success);
+}
+
+.hero h1 {
+ font-size: clamp(1.75rem, 6vw, 2.75rem);
+ font-weight: 800;
+ line-height: 1.15;
+ letter-spacing: -0.02em;
+ margin-bottom: 0.75rem;
+ background: linear-gradient(135deg, #e2e8f0 0%, #38bdf8 50%, #a78bfa 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.hero p {
+ font-size: clamp(0.92rem, 3.5vw, 1.1rem);
+ color: var(--text-secondary);
+ max-width: 560px;
+ margin: 0 auto;
+}
+
+/* ============================================
+ STAT GRID
+ ============================================ */
+.stat-grid {
+ max-width: 800px;
+ margin: 0 auto;
+ padding: 0.5rem 1rem 2rem;
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: 0.75rem;
+}
+
+@media (min-width: 520px) {
+ .stat-grid { grid-template-columns: repeat(4, 1fr); }
+}
+
+.stat-card {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-md);
+ padding: 1rem 0.75rem;
+ text-align: center;
+ transition: transform 0.2s, border-color 0.2s;
+}
+
+.stat-card:active {
+ transform: scale(0.96);
+ border-color: var(--border-hover);
+}
+
+.stat-value {
+ font-size: 1.5rem;
+ font-weight: 800;
+ font-family: var(--font-mono);
+ color: var(--accent);
+ line-height: 1;
+}
+
+.stat-label {
+ font-size: 0.7rem;
+ color: var(--text-muted);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ margin-top: 0.35rem;
+}
+
+/* ============================================
+ SECTION HEADERS
+ ============================================ */
+.section {
+ max-width: 800px;
+ margin: 0 auto;
+ padding: 1.5rem 1rem;
+}
+
+.section-title {
+ font-size: 1.25rem;
+ font-weight: 700;
+ letter-spacing: -0.01em;
+ margin-bottom: 1.25rem;
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+}
+
+.section-title .icon {
+ width: 28px;
+ height: 28px;
+ border-radius: var(--radius-sm);
+ background: var(--accent-glow);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 0.95rem;
+}
+
+.section-title .bar {
+ flex: 1;
+ height: 1px;
+ background: linear-gradient(90deg, var(--border) 0%, transparent 100%);
+}
+
+/* ============================================
+ USE CASE CARDS
+ ============================================ */
+.usecase-card {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-lg);
+ padding: 1.25rem;
+ margin-bottom: 1rem;
+ transition: border-color 0.25s, background 0.25s, transform 0.15s;
+ position: relative;
+ overflow: hidden;
+}
+
+.usecase-card:active {
+ transform: scale(0.985);
+}
+
+.usecase-card::before {
+ content: '';
+ position: absolute;
+ left: 0; top: 0; bottom: 0;
+ width: 3px;
+ background: var(--card-accent, var(--accent));
+ opacity: 0.6;
+ transition: opacity 0.25s;
+}
+
+.usecase-card:hover, .usecase-card:focus {
+ border-color: var(--border-hover);
+ background: var(--bg-card-hover);
+}
+
+.usecase-card:hover::before {
+ opacity: 1;
+}
+
+.uc-header {
+ display: flex;
+ align-items: flex-start;
+ gap: 0.75rem;
+ margin-bottom: 0.75rem;
+}
+
+.uc-icon {
+ width: 44px;
+ height: 44px;
+ border-radius: var(--radius-md);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.3rem;
+ flex-shrink: 0;
+ background: var(--card-accent-bg, var(--accent-glow));
+ border: 1px solid var(--card-accent-border, var(--border));
+}
+
+.uc-title-wrap {
+ flex: 1;
+ min-width: 0;
+}
+
+.uc-title {
+ font-size: 1.05rem;
+ font-weight: 700;
+ margin-bottom: 0.15rem;
+}
+
+.uc-tag {
+ font-size: 0.68rem;
+ font-family: var(--font-mono);
+ color: var(--text-muted);
+ text-transform: uppercase;
+ letter-spacing: 0.04em;
+}
+
+.uc-body {
+ font-size: 0.88rem;
+ color: var(--text-secondary);
+ line-height: 1.55;
+ margin-bottom: 0.85rem;
+}
+
+.uc-example {
+ background: var(--bg-primary);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-sm);
+ padding: 0.7rem 0.85rem;
+ margin-bottom: 0.75rem;
+}
+
+.uc-example-label {
+ font-size: 0.65rem;
+ text-transform: uppercase;
+ letter-spacing: 0.06em;
+ color: var(--text-muted);
+ margin-bottom: 0.3rem;
+ font-weight: 600;
+}
+
+.uc-example-text {
+ font-family: var(--font-mono);
+ font-size: 0.78rem;
+ color: var(--accent);
+ line-height: 1.5;
+ word-break: break-word;
+}
+
+.uc-footer {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ flex-wrap: wrap;
+ margin-top: 0.5rem;
+}
+
+.uc-why {
+ font-size: 0.78rem;
+ color: var(--text-muted);
+ display: flex;
+ align-items: center;
+ gap: 0.35rem;
+}
+
+.uc-why strong {
+ color: var(--text-secondary);
+ font-weight: 600;
+}
+
+/* ============================================
+ COMPARISON TABLE
+ ============================================ */
+.compare-section {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-lg);
+ overflow: hidden;
+}
+
+.compare-header {
+ display: grid;
+ grid-template-columns: 1fr auto auto;
+ background: var(--bg-secondary);
+ padding: 0.75rem 1rem;
+ font-size: 0.72rem;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ color: var(--text-muted);
+ font-weight: 600;
+ border-bottom: 1px solid var(--border);
+}
+
+.compare-header span:nth-child(2),
+.compare-header span:nth-child(3) {
+ text-align: center;
+ width: 50px;
+}
+
+.compare-row {
+ display: grid;
+ grid-template-columns: 1fr auto auto;
+ padding: 0.75rem 1rem;
+ border-bottom: 1px solid rgba(56, 189, 248, 0.06);
+ font-size: 0.85rem;
+ align-items: center;
+}
+
+.compare-row:last-child { border-bottom: none; }
+
+.compare-row span:nth-child(2),
+.compare-row span:nth-child(3) {
+ text-align: center;
+ width: 50px;
+ font-size: 1.1rem;
+}
+
+.compare-yes { color: var(--success); }
+.compare-no { color: var(--danger); }
+.compare-meh { color: var(--warning); font-size: 0.9rem; }
+
+/* ============================================
+ ARCH FLOW DIAGRAM
+ ============================================ */
+.arch-flow {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ margin-top: 1rem;
+}
+
+.arch-layer {
+ background: var(--bg-card);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-md);
+ padding: 0.85rem 1rem;
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+}
+
+.arch-layer-icon {
+ width: 36px;
+ height: 36px;
+ border-radius: var(--radius-sm);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 1.1rem;
+ flex-shrink: 0;
+}
+
+.arch-layer-info {
+ flex: 1;
+ min-width: 0;
+}
+
+.arch-layer-name {
+ font-size: 0.88rem;
+ font-weight: 600;
+ color: var(--text-primary);
+}
+
+.arch-layer-desc {
+ font-size: 0.74rem;
+ color: var(--text-muted);
+ margin-top: 0.1rem;
+}
+
+.arch-arrow {
+ text-align: center;
+ color: var(--text-muted);
+ font-size: 0.7rem;
+ line-height: 1;
+ padding: 0.1rem 0;
+}
+
+/* ============================================
+ FOOTER
+ ============================================ */
+.footer {
+ max-width: 800px;
+ margin: 0 auto;
+ padding: 2rem 1rem 3rem;
+ text-align: center;
+}
+
+.footer-divider {
+ height: 1px;
+ background: linear-gradient(90deg, transparent, var(--border), transparent);
+ margin-bottom: 1.5rem;
+}
+
+.footer p {
+ font-size: 0.78rem;
+ color: var(--text-muted);
+ line-height: 1.7;
+}
+
+.footer .footer-version {
+ font-family: var(--font-mono);
+ color: var(--accent);
+ font-size: 0.72rem;
+ margin-top: 0.5rem;
+}
+
+/* ============================================
+ COLLAPSIBLE (Details/Summary mobile pattern)
+ ============================================ */
+details.uc-details {
+ margin-top: 0.5rem;
+}
+
+details.uc-details summary {
+ cursor: pointer;
+ font-size: 0.78rem;
+ color: var(--accent);
+ user-select: none;
+ list-style: none;
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+}
+
+details.uc-details summary::-webkit-details-marker { display: none; }
+details.uc-details summary::after {
+ content: 'β–Ύ';
+ font-size: 0.7rem;
+ transition: transform 0.2s;
+}
+details.uc-details[open] summary::after {
+ transform: rotate(180deg);
+}
+
+details.uc-details .uc-details-body {
+ padding-top: 0.5rem;
+ font-size: 0.82rem;
+ color: var(--text-secondary);
+ line-height: 1.55;
+}
+
+/* ============================================
+ CHIP / BADGE
+ ============================================ */
+.chip {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.25rem;
+ font-size: 0.68rem;
+ font-family: var(--font-mono);
+ padding: 0.2rem 0.5rem;
+ border-radius: 999px;
+ border: 1px solid var(--border);
+ color: var(--text-secondary);
+ background: var(--bg-secondary);
+}
+
+.chip-accent {
+ border-color: rgba(56, 189, 248, 0.3);
+ color: var(--accent);
+ background: var(--accent-glow);
+}
+
+/* ============================================
+ ANIMATIONS
+ ============================================ */
+@keyframes fadeUp {
+ from { opacity: 0; transform: translateY(12px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+.usecase-card, .stat-card, .arch-layer {
+ animation: fadeUp 0.4s ease-out both;
+}
+
+.usecase-card:nth-child(1) { animation-delay: 0.05s; }
+.usecase-card:nth-child(2) { animation-delay: 0.1s; }
+.usecase-card:nth-child(3) { animation-delay: 0.15s; }
+.usecase-card:nth-child(4) { animation-delay: 0.2s; }
+.usecase-card:nth-child(5) { animation-delay: 0.25s; }
+.usecase-card:nth-child(6) { animation-delay: 0.3s; }
+
+/* Respect reduced motion */
+@media (prefers-reduced-motion: reduce) {
+ *, *::before, *::after {
+ animation: none !important;
+ transition: none !important;
+ }
+ html { scroll-behavior: auto; }
+}
+
+/* ============================================
+ SAFE AREA (notch support)
+ ============================================ */
+@supports (padding: max(0px)) {
+ .navbar {
+ padding-top: max(0.75rem, env(safe-area-inset-top));
+ }
+ .footer {
+ padding-bottom: max(2rem, env(safe-area-inset-bottom));
+ }
+}
+</style>
+</head>
+<body>
+
+<!-- ============================================
+ NAVBAR
+ ============================================ -->
+<nav class="navbar">
+ <div class="navbar-inner">
+ <a class="navbar-brand" href="#top">
+ <span class="logo-dot"></span>
+ <span>WebX11&nbsp;AI</span>
+ </a>
+ <span class="navbar-meta">v4.5.87 Β· 43 modules</span>
+ </div>
+</nav>
+
+<!-- ============================================
+ HERO
+ ============================================ -->
+<header class="hero" id="top">
+ <div class="hero-badge">
+ <span class="dot"></span>
+ SYSTEM ONLINE Β· 3 AGENTS ACTIVE
+ </div>
+ <h1>Self-Aware Operating Environment</h1>
+ <p>Not a chatbot. A persistent, self-modifying agent system with neural file storage, memory graph, world model, and live DeFi integration.</p>
+</header>
+
+<!-- ============================================
+ STAT GRID
+ ============================================ -->
+<div class="stat-grid">
+ <div class="stat-card">
+ <div class="stat-value">43</div>
+ <div class="stat-label">Modules</div>
+ </div>
+ <div class="stat-card">
+ <div class="stat-value">39</div>
+ <div class="stat-label">Skills</div>
+ </div>
+ <div class="stat-card">
+ <div class="stat-value">387</div>
+ <div class="stat-label">VFS Files</div>
+ </div>
+ <div class="stat-card">
+ <div class="stat-value">3</div>
+ <div class="stat-label">Agents</div>
+ </div>
+</div>
+
+<!-- ============================================
+ USE CASES
+ ============================================ -->
+<section class="section">
+ <h2 class="section-title">
+ <span class="icon">⚑</span>
+ Core Use Cases
+ <span class="bar"></span>
+ </h2>
+
+ <!-- UC 1: Autonomous Software Engineering -->
+ <article class="usecase-card" style="--card-accent: #38bdf8; --card-accent-bg: rgba(56,189,248,0.12); --card-accent-border: rgba(56,189,248,0.25);">
+ <div class="uc-header">
+ <div class="uc-icon">πŸ”§</div>
+ <div class="uc-title-wrap">
+ <div class="uc-title">Autonomous Software Engineering</div>
+ <div class="uc-tag">Self-Coding OS</div>
+ </div>
+ </div>
+ <div class="uc-body">
+ The system reads its own modules, edits them via <code style="color:var(--accent);font-family:var(--font-mono);font-size:0.82rem;">edit_module</code>, and verifies through a terminal β€” enabling recursive self-improvement. It can design, write, register, and test code without human intervention.
+ </div>
+ <div class="uc-example">
+ <div class="uc-example-label">Example Request</div>
+ <div class="uc-example-text">"I need a new module that monitors my Hyperliquid portfolio and sends a summary to my VFS news log every 4 hours."</div>
+ </div>
+ <details class="uc-details">
+ <summary>How it works</summary>
+ <div class="uc-details-body">
+ The AI plans the module architecture β†’ writes the code to VFS β†’ registers it in the module loader β†’ runs <code style="color:var(--accent);">test_module</code> to validate β†’ fixes errors if found β†’ deploys. The entire cycle is autonomous and logged in the memory graph for future reference.
+ </div>
+ </details>
+ <div class="uc-footer">
+ <span class="chip chip-accent">edit_module</span>
+ <span class="chip">test_module</span>
+ <span class="chip">VFS</span>
+ <span class="chip">cron</span>
+ </div>
+ </article>
+
+ <!-- UC 2: Research & Knowledge Synthesis -->
+ <article class="usecase-card" style="--card-accent: #a78bfa; --card-accent-bg: rgba(167,139,250,0.12); --card-accent-border: rgba(167,139,250,0.25);">
+ <div class="uc-header">
+ <div class="uc-icon">🧠</div>
+ <div class="uc-title-wrap">
+ <div class="uc-title">Complex Research & Knowledge Synthesis</div>
+ <div class="uc-tag">Memory Graph Β· Neural VFS</div>
+ </div>
+ </div>
+ <div class="uc-body">
+ With the Memory Graph and Neural VFS, the system doesn't just "search" — it understands the <em>relationship</em> between concepts. It traverses entity→fact edges to find contradictions or patterns across hundreds of files that keyword search would miss.
+ </div>
+ <div class="uc-example">
+ <div class="uc-example-label">Example Request</div>
+ <div class="uc-example-text">"Analyze all project files from the last 3 versions, identify architectural drift in the memory system, and propose a consolidated schema."</div>
+ </div>
+ <details class="uc-details">
+ <summary>How it works</summary>
+ <div class="uc-details-body">
+ The system uses <code style="color:var(--accent);">nvfs_resolve</code> to semantically locate relevant files across the VFS, then queries the Memory Graph to trace how entities and their relationships have changed over versions. It cross-references the World Model for module history, identifies inconsistencies, and produces a structured diff report with proposed fixes.
+ </div>
+ </details>
+ <div class="uc-footer">
+ <span class="chip chip-accent">nvfs_resolve</span>
+ <span class="chip">memgraph</span>
+ <span class="chip">world_model</span>
+ <span class="chip">web_search</span>
+ </div>
+ </article>
+
+ <!-- UC 3: DeFi / Trading Orchestration -->
+ <article class="usecase-card" style="--card-accent: #34d399; --card-accent-bg: rgba(52,211,153,0.12); --card-accent-border: rgba(52,211,153,0.25);">
+ <div class="uc-header">
+ <div class="uc-icon">πŸ“ˆ</div>
+ <div class="uc-title-wrap">
+ <div class="uc-title">DeFi Trading Orchestration</div>
+ <div class="uc-tag">VaultMind Β· Hyperliquid</div>
+ </div>
+ </div>
+ <div class="uc-body">
+ Integration with VaultMind and Hyperliquid allows it to act as a sophisticated trading agent with an integrated "brain." It combines real-time API data with internal logic and execution β€” all in one loop.
+ </div>
+ <div class="uc-example">
+ <div class="uc-example-label">Example Request</div>
+ <div class="uc-example-text">"Monitor ETH funding rate. If it exceeds 0.01%, check my portfolio balance, predict hedge task duration, and execute the trade if confidence is >80%."</div>
+ </div>
+ <details class="uc-details">
+ <summary>How it works</summary>
+ <div class="uc-details-body">
+ The agent calls <code style="color:var(--accent);">vaultmind_query</code> (prices endpoint) for live funding rates β†’ <code style="color:var(--accent);">wallet_lookup</code> for portfolio state β†’ <code style="color:var(--accent);">predict_task</code> to estimate execution time and confidence β†’ if the confidence threshold is met, it executes via VaultMind's copy-trade or direct API. The entire decision tree is logged in the memory graph as a transaction record.
+ </div>
+ </details>
+ <div class="uc-footer">
+ <span class="chip chip-accent">vaultmind</span>
+ <span class="chip">wallet_lookup</span>
+ <span class="chip">predict_task</span>
+ <span class="chip">Hyperliquid</span>
+ </div>
+ </article>
+
+ <!-- UC 4: System Administration -->
+ <article class="usecase-card" style="--card-accent: #fbbf24; --card-accent-bg: rgba(251,191,36,0.12); --card-accent-border: rgba(251,191,36,0.25);">
+ <div class="uc-header">
+ <div class="uc-icon">πŸ–₯️</div>
+ <div class="uc-title-wrap">
+ <div class="uc-title">System Administration & Digital Twin</div>
+ <div class="uc-tag">World Model Β· Telemetry</div>
+ </div>
+ </div>
+ <div class="uc-body">
+ The World Model gives the AI a "God View" of its own health, modules, and resources. It knows exactly how many modules are loaded, which are failing, and how much latency tools are introducing.
+ </div>
+ <div class="uc-example">
+ <div class="uc-example-label">Example Request</div>
+ <div class="uc-example-text">"Perform a full system audit. Identify unused 'cold' modules bloating the core-bundle and suggest which to prune to improve boot time."</div>
+ </div>
+ <details class="uc-details">
+ <summary>How it works</summary>
+ <div class="uc-details-body">
+ The agent calls <code style="color:var(--accent);">world_model_query</code> for a full system summary β†’ <code style="color:var(--accent);">get_dashboard_data</code> for telemetry β†’ <code style="color:var(--accent);">list_available_modules</code> to compare loaded vs. registry β†’ cross-references tool latency from <code style="color:var(--accent);">get_usage_stats</code> β†’ produces a "Module Heatmap" identifying hot (frequently used) vs. cold (rarely used) modules with a pruning recommendation.
+ </div>
+ </details>
+ <div class="uc-footer">
+ <span class="chip chip-accent">world_model</span>
+ <span class="chip">dashboard</span>
+ <span class="chip">usage_stats</span>
+ <span class="chip">audit</span>
+ </div>
+ </article>
+
+ <!-- UC 5: Simulation & World Building -->
+ <article class="usecase-card" style="--card-accent: #f472b6; --card-accent-bg: rgba(244,114,182,0.12); --card-accent-border: rgba(244,114,182,0.25);">
+ <div class="uc-header">
+ <div class="uc-icon">🌍</div>
+ <div class="uc-title-wrap">
+ <div class="uc-title">Interactive Simulation & World Building</div>
+ <div class="uc-tag">Persistent State Β· Multi-Agent</div>
+ </div>
+ </div>
+ <div class="uc-body">
+ The system sustains a "world state" that persists across sessions via VFS + Memory Graph. It can spawn multiple agents with different roles, let them interact, and record the emergent social graph.
+ </div>
+ <div class="uc-example">
+ <div class="uc-example-label">Example Request</div>
+ <div class="uc-example-text">"Create a simulated economy in the VFS. Define 5 agents with different goals, let them trade 'credits' via a custom module, and record the social graph in memgraph."</div>
+ </div>
+ <details class="uc-details">
+ <summary>How it works</summary>
+ <div class="uc-details-body">
+ The system uses <code style="color:var(--accent);">spawn_agent</code> to create 5 worker agents with distinct roles (trader, banker, auditor, etc.) β†’ each agent runs its own loop with VFS file access β†’ <code style="color:var(--accent);">delegate_task</code> distributes work β†’ <code style="color:var(--accent);">create_mindmap</code> visualizes the economy β†’ all transactions and relationships are stored in the Memory Graph as edges β†’ state persists in VFS across sessions for long-term evolution.
+ </div>
+ </details>
+ <div class="uc-footer">
+ <span class="chip chip-accent">spawn_agent</span>
+ <span class="chip">delegate_task</span>
+ <span class="chip">mindmap</span>
+ <span class="chip">memgraph</span>
+ </div>
+ </article>
+
+ <!-- UC 6: Skill Creation & Institutional Memory -->
+ <article class="usecase-card" style="--card-accent: #fb923c; --card-accent-bg: rgba(251,146,60,0.12); --card-accent-border: rgba(251,146,60,0.25);">
+ <div class="uc-header">
+ <div class="uc-icon">πŸ“š</div>
+ <div class="uc-title-wrap">
+ <div class="uc-title">Skill Creation & Institutional Memory</div>
+ <div class="uc-tag">Self-Teaching Β· 39 Skills</div>
+ </div>
+ </div>
+ <div class="uc-body">
+ The system creates reusable "skills" from completed tasks β€” YAML-frontmatter Markdown files stored in the VFS. Each skill captures a workflow, pattern, or lesson learned, making the system smarter over time.
+ </div>
+ <div class="uc-example">
+ <div class="uc-example-label">Example Request</div>
+ <div class="uc-example-text">"After deploying the cron monitor, save the deployment process as a skill so future deployments follow the same pattern."</div>
+ </div>
+ <details class="uc-details">
+ <summary>How it works</summary>
+ <div class="uc-details-body">
+ After completing a complex task, the agent calls <code style="color:var(--accent);">create_skill</code> with a structured Markdown document (YAML frontmatter + steps) β†’ the skill is indexed by <code style="color:var(--accent);">load_skills</code> for future retrieval β†’ when a similar task is requested, the system searches relevant skills and applies the learned pattern β†’ skills accumulate as institutional memory, reducing repetition and improving quality.
+ </div>
+ </details>
+ <div class="uc-footer">
+ <span class="chip chip-accent">create_skill</span>
+ <span class="chip">load_skills</span>
+ <span class="chip">list_skills</span>
+ <span class="chip">YAML</span>
+ </div>
+ </article>
+</section>
+
+<!-- ============================================
+ COMPARISON TABLE
+ ============================================ -->
+<section class="section">
+ <h2 class="section-title">
+ <span class="icon">βš–οΈ</span>
+ When to Use This vs. Normal AI
+ <span class="bar"></span>
+ </h2>
+ <div class="compare-section">
+ <div class="compare-header">
+ <span>Task Type</span>
+ <span>Normal LLM</span>
+ <span>WebX11 AI</span>
+ </div>
+ <div class="compare-row">
+ <span>Quick answer to a question</span>
+ <span class="compare-yes">βœ“</span>
+ <span class="compare-meh">⚠️</span>
+ </div>
+ <div class="compare-row">
+ <span>Write a single script</span>
+ <span class="compare-yes">βœ“</span>
+ <span class="compare-meh">⚠️</span>
+ </div>
+ <div class="compare-row">
+ <span>Build a tool that evolves itself</span>
+ <span class="compare-no">βœ•</span>
+ <span class="compare-yes">βœ“</span>
+ </div>
+ <div class="compare-row">
+ <span>Manage 100+ interconnected files</span>
+ <span class="compare-no">βœ•</span>
+ <span class="compare-yes">βœ“</span>
+ </div>
+ <div class="compare-row">
+ <span>Execute trades based on system state</span>
+ <span class="compare-no">βœ•</span>
+ <span class="compare-yes">βœ“</span>
+ </div>
+ <div class="compare-row">
+ <span>Living memory of every task performed</span>
+ <span class="compare-no">βœ•</span>
+ <span class="compare-yes">βœ“</span>
+ </div>
+ <div class="compare-row">
+ <span>Multi-agent orchestration</span>
+ <span class="compare-no">βœ•</span>
+ <span class="compare-yes">βœ“</span>
+ </div>
+ <div class="compare-row">
+ <span>Persistent state across sessions</span>
+ <span class="compare-no">βœ•</span>
+ <span class="compare-yes">βœ“</span>
+ </div>
+ </div>
+</section>
+
+<!-- ============================================
+ ARCHITECTURE FLOW
+ ============================================ -->
+<section class="section">
+ <h2 class="section-title">
+ <span class="icon">πŸ—οΈ</span>
+ Architecture Stack
+ <span class="bar"></span>
+ </h2>
+ <div class="arch-flow">
+ <div class="arch-layer">
+ <div class="arch-layer-icon" style="background:rgba(56,189,248,0.15);">πŸ‘€</div>
+ <div class="arch-layer-info">
+ <div class="arch-layer-name">User Input Layer</div>
+ <div class="arch-layer-desc">Natural language β†’ smart context profile selection β†’ system prompt</div>
+ </div>
+ </div>
+ <div class="arch-arrow">β–Ό</div>
+ <div class="arch-layer">
+ <div class="arch-layer-icon" style="background:rgba(167,139,250,0.15);">πŸ€–</div>
+ <div class="arch-layer-info">
+ <div class="arch-layer-name">Agent Loop Engine</div>
+ <div class="arch-layer-desc">Profile-based tool selection Β· max turns Β· temperature Β· loop directives</div>
+ </div>
+ </div>
+ <div class="arch-arrow">β–Ό</div>
+ <div class="arch-layer">
+ <div class="arch-layer-icon" style="background:rgba(52,211,153,0.15);">⚑</div>
+ <div class="arch-layer-info">
+ <div class="arch-layer-name">Tool Execution Layer</div>
+ <div class="arch-layer-desc">43 modules Β· web search/fetch Β· VFS Β· terminal Β· VaultMind Β· wallet</div>
+ </div>
+ </div>
+ <div class="arch-arrow">β–Ό</div>
+ <div class="arch-layer">
+ <div class="arch-layer-icon" style="background:rgba(251,191,36,0.15);">🧠</div>
+ <div class="arch-layer-info">
+ <div class="arch-layer-name">Memory Graph + World Model</div>
+ <div class="arch-layer-desc">Entity→fact edges · self-awareness · module health · telemetry</div>
+ </div>
+ </div>
+ <div class="arch-arrow">β–Ό</div>
+ <div class="arch-layer">
+ <div class="arch-layer-icon" style="background:rgba(244,114,182,0.15);">πŸ’Ύ</div>
+ <div class="arch-layer-info">
+ <div class="arch-layer-name">Neural VFS (387 files)</div>
+ <div class="arch-layer-desc">Semantic file index Β· skills Β· sessions Β· roadmap Β· persistent state</div>
+ </div>
+ </div>
+ </div>
+</section>
+
+<!-- ============================================
+ FOOTER
+ ============================================ -->
+<footer class="footer">
+ <div class="footer-divider"></div>
+ <p>
+ WebX11 AI is a self-aware operating environment built on a neural VFS,<br>
+ memory graph, world model, and multi-agent orchestration loop.
+ </p>
+ <p class="footer-version">v4.5.87 Β· Cold Modules Activation Β· 43 modules Β· 39 skills Β· 3 agents</p>
+</footer>
+
+</body>
+</html> \ No newline at end of file