FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/pages/Jobs.jsx 00031: useEffect(() => { load(); }, []); 00032: 00033: const submit = async () => { 00034: if (!selected) return; 00035: setBusy(true); 00036: let request = { simulation: true, project_id: selected }; 00037: try { 00038: const project = await base44.entities.CoverCanvasProject.get(selected); 00039: const [layers, assets] = await Promise.all([ 00040: base44.entities.ArtworkLayer.filter({ projectId: selected }).catch(() => []), 00041: base44.entities.ArtworkAsset.filter({ projectId: selected }).catch(() => []) 00042: ]); 00043: let cover = null; ... 00045: request = buildGeometryRequest({ project, cover, layers: Array.isArray(layers) ? layers : [], assets: Array.isArray(assets) ? assets : [] }); 00046: } catch { /* fall back to minimal request */ } 00047: try { 00048: const job = await base44.entities.GeometryJob.create({ projectId: selected, jobType: 'projection_preview', status: 'processing', progress: 20, requestPayload: request }); 00049: await GeometryService.createProjectionPreview(request); 00050: await base44.entities.GeometryJob.update(job.id, { status: 'completed', progress: 100, completedDate: new Date().toISOString(), resultPayload: { simulation: true, request } }); 00051: } catch { /* simulation best-effort */ } 00052: setBusy(false); 00053: load(); 00054: }; 00055: const canFinal = storageAdapter.canFinalize(settings); 00056: const safeJobs = Array.isArray(jobs) ? jobs : []; 00057: const safeProjects = Array.isArray(projects) ? projects : []; 00058: 00059: return ( 00060: <> 00061: 00062: 00063:
00064: 00065: 00066: 00067:
00068:
{guided ? 'Final processing is unavailable until the live geometry engine and SHiRE storage are connected.' : 'Final processing is blocked until the deployment adapter verifies a live geometry service and writable SHiREVault at /SHiRELimbs.'}
00069: 00070:
00071:

{guided ? 'Your processing jobs' : 'Job queue'}

00072: {safeJobs.map(j => { ... 00079:

{j.id.slice(0, 12)}

00080:
00081: {!guided && ( 00082:
00083:

Operation: {j.jobType?.replaceAll('_', ' ')}

00084:

Engine: {j.simulation ? 'simulation' : 'live'}

00085:
00086: )} 00087:
00088:
00089:
00090:
00091: {j.progress}% FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/pages/Dashboard.jsx 00061: const activeJobs = safeJobs.filter(j => j.status === 'processing' || j.status === 'queued'); 00062: const jobCountByProject = safeJobs.reduce((m, j) => { m[j.projectId] = (m[j.projectId] || 0) + 1; return m; }, {}); 00063: const alerts = safeProjects.filter(p => p.validationStatus === 'warning' || p.validationStatus === 'fail'); 00064: 00065: const geoStatus = d.settings?.geometryServiceStatus; 00066: const engineTone = geoStatus === 'connected' ? 'ok' : geoStatus === 'simulation_only' ? 'sim' : 'idle'; 00067: const engineLabel = geoStatus === 'connected' ? 'Ready' : geoStatus === 'simulation_only' ? 'Preview only' : 'Offline'; 00068: const vaultOk = d.settings?.shireVaultStatus === 'connected' && d.settings?.shireVaultWritable; 00069: const storageLabel = vaultOk ? 'Connected' : 'Not connected'; 00070: const storageTone = vaultOk ? 'ok' : 'warn'; 00071: const recentVariant = safeVariants[0]; 00072: 00073: return ( 00074: <> FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/pages/UniversalDesignCanvas.jsx 00199:
00200: Open fitted version 00201: 00202: 00203:
00204:

Simulation only — final surface fitting requires the Geometry Engine.

00205:
00206: ) : ( 00207: <> 00208:
00209: setStage('create')} onRemove={() => { setPieces([]); setFocalId(null); setSelectedId(null); setPast([]); setFuture([]); }} onPrepare={() => setStage('arrange')} /> 00211:
FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/pages/Validation.jsx 00013: 'Minimum line thickness', 'Minimum feature size', 'Artwork within decoration zone', 00014: 'No overlap with protected zones', 'Minimum wall thickness passed', 'Attachment geometry preserved', 00015: 'Ossiguard area preserved', 'Required SHiRE logo present', 'Geometry service connected', 00016: 'Real geometry generated', 'Manifold mesh passed', 'Final export available' 00017: ]; 00018: const icons = { pass: CheckCircle2, warning: AlertTriangle, fail: XCircle, not_checked: Clock3, simulation_only: Clock3 }; 00019: 00020: const groups = [ 00021: ['Cover integrity', ['Cover loaded successfully']], 00022: ['Artwork quality', ['Drawing loaded successfully', 'Drawing resolution adequate', 'Drawing cleaned', 'Minimum line thickness', 'Minimum feature size', 'Artwork within decoration zone']], 00023: ['Prosthetic clearance', ['No overlap with protected zones', 'Minimum wall thickness passed']], 00024: ['Connector preservation', ['Attachment geometry preserved', 'Ossiguard area preserved']], 00025: ['Manufacturing readiness', ['Geometry service connected', 'Real geometry generated', 'Manifold mesh passed', 'Final export available']], ... 00095: layers = Array.isArray(l) ? l : []; 00096: assets = Array.isArray(a) ? a : []; 00097: if (project?.coverModelId) { try { cover = await base44.entities.CoverModel.get(project.coverModelId); } catch { cover = null; } } 00098: } catch { /* project data optional for preview */ } 00099: 00100: // Best-effort simulation call; never used to infer a real pass. 00101: try { await GeometryService.validateGeometry(buildGeometryRequest({ project, cover, layers, assets })); } catch { /* offline — fine */ } 00102: 00103: const svcConnected = settings?.geometryServiceStatus === 'connected'; 00104: const vaultOk = storageAdapter.canFinalize(settings); 00105: 00106: // Evidence (only these can be confirmed in the browser). 00107: const hasProject = !!project; ... 00135: case 'Minimum feature size': 00136: case 'Minimum wall thickness passed': 00137: case 'Attachment geometry preserved': 00138: case 'Ossiguard area preserved': 00139: case 'Manifold mesh passed': 00140: return { name, status: 'simulation_only', note: 'Confirmed by the real Geometry Engine during processing.' }; 00141: case 'Real geometry generated': 00142: return { name, status: 'simulation_only', note: 'Browser preview only — real geometry is produced by the external engine.' }; 00143: case 'Final export available': 00144: return { name, status: 'fail', note: 'Final export needs real geometry and verified SHiRE storage.' }; 00145: default: 00146: return { name, status: 'not_checked' }; 00147: } 00148: }); 00149: setChecks(next); 00150: const failCount = next.filter(c => c.status === 'fail').length; 00151: const pending = next.filter(c => c.status === 'simulation_only' || c.status === 'not_checked' || c.status === 'warning').length; 00152: setOverall(failCount > 0 ? 'CANNOT CONTINUE YET' : pending > 0 ? 'NEEDS A SMALL CHANGE' : 'READY FOR REAL 3D PROCESSING'); 00153: try { 00154: await base44.entities.ValidationReport.create({ 00155: projectId, overallStatus: failCount > 0 ? 'fail' : 'simulation_only', checks: next, 00156: warnings: ['Preview checks are not manufacturing validation.'], failures: next.filter(c => c.status === 'fail').map(c => c.name), 00157: generatedDate: new Date().toISOString() 00158: }); 00159: } catch { /* non-fatal */ } 00160: setBusy(false); 00161: }; 00162: 00163: const blocked = checks.some(x => x.status === 'fail' || x.status === 'not_checked' || x.status === 'simulation_only' || x.status === 'warning') || !storageAdapter.canFinalize(settings); 00164: const toggle = (g) => setOpen(s => { const n = new Set(s); n.has(g) ? n.delete(g) : n.add(g); return n; }); 00165: const checkByName = (n) => checks.find(c => c.name === n) || { status: 'not_checked' }; 00166: 00167: const overallTone = overall === 'READY FOR REAL 3D PROCESSING' ? 'ok' : overall === 'NEEDS A SMALL CHANGE' ? 'warn' : overall === 'CANNOT CONTINUE YET' ? 'bad' : 'idle'; 00168: const overallClass = overallTone === 'ok' ? 'text-emerald-300 border-emerald-400/40 bg-emerald-400/10' 00169: : overallTone === 'warn' ? 'text-amber-200 border-amber-400/40 bg-amber-400/10' 00170: : overallTone === 'bad' ? 'text-red-300 border-red-500/40 bg-red-500/10' ... 00174: return ( 00175: <> 00176: {busy ? 'Checking…' : 'Run checks'}} /> 00177:
00178:

{busy ? 'Checking your design…' : overall === 'NOT CHECKED' ? 'Not checked yet' : overall}

00179:

{overall === 'READY FOR REAL 3D PROCESSING' ? 'Everything we can check in the browser looks good. Submit for real 3D processing to finish.' : 'Some checks need attention. Items marked Simulation require the real Geometry Engine.'}

00180:
00181: 00182:
00183: {friendlyGroups.map(group => { 00184: const groupChecks = group.checks.map(checkByName); 00185: const groupFail = groupChecks.some(c => c.status === 'fail'); 00186: return ( ... 00197: const needsFix = c.status === 'fail' || c.status === 'warning'; 00198: const fa = fixAction(c.name, projectId); 00199: return ( 00200:
00201:
00202: 00203:

{f.what}

00204: 00205:
00206: {c.status !== 'pass' &&

{f.why}{c.note ? ` ${c.note}` : ''}

} 00207: {needsFix && ( 00208:
00209: ... 00236:
3D Preview — final printable geometry not yet generated. Real wall, manifold, clearance and export checks require the external geometry engine and SHiREVault.
00237: 00238:
00239: {groups.map(([label, groupNames]) => { 00240: const groupChecks = groupNames.map(checkByName); 00241: const counts = { pass: 0, warning: 0, fail: 0, not_checked: 0, simulation_only: 0 }; 00242: groupChecks.forEach(c => counts[c.status] = (counts[c.status] || 0) + 1); 00243: const isOpen = open.has(label); 00244: return ( 00245:
00246: 00259: {isOpen && ( 00260:
00261: {groupChecks.map(c => { 00262: const Icon = icons[c.status] || Clock3; 00263: return ( 00264:
00265: 00266:

{c.name}

{c.note &&

{c.note}

}
00267: 00268:
00269: ); 00270: })} 00271:
00272: )} FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/pages/Settings.jsx 00007: import { storageAdapter } from '@/lib/storageAdapter'; 00008: 00009: const defaults = { 00010: geometryServiceUrl: 'https://geometry.shire.example/v1', geometryServiceAuth: 'none', healthCheckEndpoint: '/health', 00011: maxUploadSize: 50, defaultEmbossHeight: 1.2, defaultEngravingDepth: 0.8, minimumFeatureSize: 0.6, minimumWallThickness: 2, 00012: geometryServiceStatus: 'simulation_only', shireVaultStatus: 'not_connected', shireVaultPath: '/SHiRELimbs', shireVaultWritable: false, 00013: aiConceptServiceUrl: 'built-in InvokeLLM', defaultStorageType: 'prototype', allowedFileFormats: ['stl', 'obj', 'glb', 'png', 'jpg', 'jpeg', 'webp', 'svg'] 00014: }; 00015: 00016: export default function Settings() { 00017: const [s, setS] = useState(defaults); 00018: const [id, setId] = useState(null); 00019: const [saved, setSaved] = useState(false); FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/pages/ProjectHistory.jsx 00056:
00057: 00070:
00071: )} FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/pages/PromptForge.jsx 00276: {(Array.isArray(concepts) ? concepts : []).map(c => { 00277: const treatment = (decorations.find(d => d[0] === c.applicationModeSuggestion) || [])[1] || c.applicationModeSuggestion; 00278: return ( 00279:
00280:
00281: {c.previewImageUrl ? :
Concept preview simulation
} 00282: Original inspired concept 00283:
00284:
00285:

{c.title}

00286:

{c.summary}

00287:
{(c.styleTags || []).map(t => {t})}
00288:
FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/pages/Studio.jsx 00296: 00297: ); 00298: 00299: return ( 00300: <> 00301: 00302:
00303: {savedAt && Draft saved} 00304: {project?.hasUnsavedChanges && Unsaved changes from a previous session recovered.} 00305:
00306: {(loadError || opError) && ( 00307:
00308: {loadError || opError} FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/lib/geometryService.js 00001: // GeometryService adapter — development mock. 00002: // Every mocked response includes simulation: true. 00003: // Never display "Print Ready", "Export Complete" or "Validated Geometry" from a simulated response. 00004: 00005: // Assemble the full LimbForge Geometry Engine request payload from project data. 00006: // Includes original + processed artwork, processing settings, layer transforms, 00007: // projection/application mode, emboss/engraving/relief/stencil settings, cover 00008: // model reference and all zone data. 00009: export function buildGeometryRequest({ project, cover, layers = [], assets = [], concept = null } = {}) { ... 00011: const assetFor = (l) => (assets || []).find(a => a.id === l?.artworkAssetId); 00012: const appMode = project?.applicationMode || 'colour_texture'; 00013: const gs = project?.geometrySettings || {}; 00014: return { 00015: project_id: project?.id || null, 00016: simulation: true, 00017: cover_model: { 00018: reference: cover?.sourceFile || null, 00019: id: cover?.id || null, 00020: name: cover?.name || null, 00021: limb_type: cover?.limbType || null, 00022: side: cover?.side || null, 00023: source_format: cover?.sourceFormat || null, ... 00079: } 00080: 00081: const simulated = (operation, extra = {}) => 00082: new Promise(resolve => setTimeout(() => resolve({ 00083: ok: true, 00084: simulation: true, 00085: operation, 00086: service_version: 'mock-0.1', 00087: ...extra 00088: }), 600)); 00089: 00090: export const GeometryService = { 00091: buildGeometryRequest, 00092: checkHealth: () => simulated('health', { status: 'simulation_only', connected: false }), 00093: uploadCover: payload => simulated('upload_cover', { cover_reference: payload?.cover_model?.reference || payload?.sourceFile || null }), 00094: uploadArtwork: payload => simulated('upload_artwork', { artwork_reference: payload?.artwork?.original_reference || payload?.originalFile || null }), 00095: generatePromptConcepts: payload => simulated('prompt_concepts', { concepts: [], prompt: payload?.promptText || '' }), 00096: createProjectionPreview: payload => simulated('projection_preview', { projection: payload?.application_mode || payload?.projectionMode || 'planar', layers: payload?.layers?.length || 0, real: false }), 00097: generateEmboss: payload => simulated('emboss', { settings: payload?.emboss, real: false }), 00098: generateEngraving: payload => simulated('engraving', { settings: payload?.engraving, real: false }), 00099: generateRelief: payload => simulated('relief', { settings: payload?.relief, real: false }), 00100: generateStencil: payload => simulated('stencil', { settings: payload?.stencil, real: false }), 00101: validateGeometry: payload => simulated('validate_geometry', { request: !!payload, real: false }), 00102: exportCover: () => Promise.resolve({ 00103: ok: false, 00104: simulation: true, 00105: blocked: true, 00106: error: 'Real geometry service and writable SHiREVault are required for export.' 00107: }), 00108: getJobStatus: id => simulated('job_status', { id, status: 'completed', progress: 100, real: false }), 00109: 00110: // --- Design-first (Universal Design → Cover Variant) adapter methods --- 00111: // All mocked with simulation: true. None of these unlock Real Geometry, 00112: // Validated, or Print Ready states. 00113: 00114: // Evaluate browser-available cover metadata for design compatibility. 00115: analyseCoverCompatibility: payload => simulated('analyse_cover_compatibility', { 00116: cover_id: payload?.coverModelId || payload?.cover?.id || null, 00117: design_id: payload?.universalDesignId || payload?.design?.id || null, 00118: level: 'requires_processing', ... 00156: }), 00157: 00158: // Export remains blocked until real geometry service + writable SHiREVault exist. 00159: exportCoverVariant: () => Promise.resolve({ 00160: ok: false, 00161: simulation: true, 00162: blocked: true, 00163: error: 'Real geometry service and writable SHiREVault are required to export a cover variant.' 00164: }) 00165: }; FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/lib/adaptation.js 00158: movedRegions: adapted.filter(a => !a.focal).map(a => ({ layer: a.name })), 00159: protectedZoneWarnings, 00160: brandingStatus: safeArr(cover?.brandingZones).length ? 'preserved' : 'unverified', 00161: summary, 00162: details, 00163: simulation: true, 00164: note: 'Browser preview only. Final surface wrapping and print checks happen during 3D processing.' 00165: }; 00166: } 00167: 00168: // Strategy options with friendly guided labels. 00169: export const GUIDED_STRATEGY_CHOICES = [ 00170: ['best_fit', 'Recommended fit'], FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/components/canvas/FitPreview.jsx 00051: Anchor: U {adaptation.anchor.u.toFixed(2)} · V {adaptation.anchor.v.toFixed(2)} 00052: Decoration rect: {adaptation.decorationRect.x.toFixed(2)},{adaptation.decorationRect.y.toFixed(2)} {adaptation.decorationRect.w.toFixed(2)}×{adaptation.decorationRect.h.toFixed(2)} 00053: Preserve aspect: {String(adaptation.distortionReport.preserveAspect)} 00054: Max scale: {adaptation.distortionReport.maxScale} 00055: Adapted layers: {adaptation.adaptedLayers.length} 00056: Simulation: {String(adaptation.simulation)} 00057:
00058: )} 00059:

Simulation only — final curved-surface fitting requires the Geometry Engine.

00060:
00061: 00062: {/* Review actions */} 00063:
00064: 00065: 00066: FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/components/studio/HeightMapPreview.jsx 00041:
00042:
00043: )} 00044:
00045: {imageUrl && ( 00046:
Browser preview — simulation only
00047: )} 00048:
00049: ); 00050: } FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/components/studio/StudioRightPanel.jsx 00026:
00027: ); 00028: } 00029: 00030: const QUICK_CHECKS = [ 00031: ['Artwork resolution', 'pass'], ['Minimum feature size', 'simulation_only'], ['Curve continuity', 'warning'], 00032: ['Connector clearance', 'simulation_only'], ['Emboss limit', 'pass'], ['Engraving limit', 'pass'], 00033: ['Protected-zone overlap', 'not_checked'], ['SHiRE branding', 'pass'], ['Print readiness', 'simulation_only'], ['Final clearance check', 'not_checked'] 00034: ]; 00035: const checkIcon = { pass: '✓', warning: '!', fail: '✕', not_checked: '•', simulation_only: '⊙' }; 00036: const checkCls = { pass: 'text-emerald-300', warning: 'text-amber-300', fail: 'text-red-300', not_checked: 'text-slate-500', simulation_only: 'text-violet-300' }; 00037: 00038: export default function StudioRightPanel({ project, cover, layers, selected, assets, onSelect, onUpdateLayer, onMove, onDuplicate, onDelete, onAddLayer, protectedVisible, onToggleProtected, onNavigate }) { 00039: const safeLayers = Array.isArray(layers) ? layers : []; 00040: const safeAssets = Array.isArray(assets) ? assets : []; 00041: const safeProtectedVisible = Array.isArray(protectedVisible) ? protectedVisible : []; 00042: const assetFor = (l) => safeAssets.find(a => a.id === l?.artworkAssetId); 00043: const zones = (Array.isArray(cover?.protectedZones) && cover.protectedZones.length) ? cover.protectedZones : STANDARD_ZONES.map(name => ({ name, status: 'not_checked' })); ... 00088:
00089: {QUICK_CHECKS.map(([n, st]) => ( 00090:
00091: {checkIcon[st]} 00092: {n} 00093: {st === 'simulation_only' ? Sim : {st.replace('_', ' ')}} 00094:
00095: ))} 00096:
00097:
00098: 00099: 00100:
FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/components/studio/CoverViewer.jsx 00328: {/* Zone overlays disabled — keep component definitions for later restoration. */} 00329: {false && showProtected && Protected zones} 00330: {false && showDecoration && Decoration zones} 00331: {false && showConnector && Connector clearance} 00332: 00333: Simulation only 00334: {safeLayers.some((l) => l.visible) && ( 00335: Preview placement — final surface projection requires Geometry Engine 00336: )} 00337:
00338: ); 00339: } FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/components/app/StatusBar.jsx 00005: return ; 00006: } 00007: 00008: export default function StatusBar({ project, settings }) { 00009: const saved = project?.updated_date ? new Date(project.updated_date).toLocaleString(undefined, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }) : '—'; 00010: const geoTone = settings?.geometryServiceStatus === 'connected' ? 'ok' : settings?.geometryServiceStatus === 'simulation_only' ? 'sim' : 'idle'; 00011: const geoLabel = settings?.geometryServiceStatus === 'connected' ? 'Online' : settings?.geometryServiceStatus === 'simulation_only' ? 'Simulation' : 'Offline'; 00012: const vaultTone = settings?.shireVaultStatus === 'connected' && settings?.shireVaultWritable ? 'ok' : 'warn'; 00013: const vaultLabel = settings?.shireVaultStatus === 'connected' ? (settings?.shireVaultWritable ? 'Synced' : 'Read-only') : 'Not mounted'; 00014: 00015: return ( 00016:
00017: Last saved {saved} 00018: Auto-save On FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/components/app/ProjectCard.jsx 00005: 00006: const inputLabel = { image_apply: 'Image Apply', sketch_3d: 'Sketch to 3D', promptforge: 'PromptForge' }; 00007: const bandColor = { 00008: pass: 'bg-emerald-400', validated: 'bg-emerald-400', ready_for_export: 'bg-emerald-400', 00009: warning: 'bg-amber-400', fail: 'bg-red-500', failed: 'bg-red-500', 00010: simulation_only: 'bg-cyan-400', not_checked: 'bg-slate-600', draft: 'bg-slate-600', 00011: artwork: 'bg-cyan-400', studio: 'bg-cyan-400', validation: 'bg-amber-400', processing: 'bg-violet-400' 00012: }; 00013: 00014: export default function ProjectCard({ project, cover, jobsCount = 0, to }) { 00015: const href = to || `/studio?project=${project.id}`; 00016: const band = bandColor[project.validationStatus] || bandColor[project.status] || 'bg-slate-600'; 00017: return ( FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/components/app/StatusBadge.jsx 00005: connected: 'border-emerald-400/30 bg-emerald-400/10 text-emerald-300 dot-emerald', 00006: warning: 'border-amber-400/30 bg-amber-400/10 text-amber-200 dot-amber', 00007: fail: 'border-red-500/40 bg-red-500/10 text-red-300 dot-red', 00008: failed: 'border-red-500/40 bg-red-500/10 text-red-300 dot-red', 00009: processing: 'border-cyan-400/30 bg-cyan-400/10 text-cyan-200 dot-cyan', 00010: simulation_only: 'border-cyan-400/30 bg-cyan-400/10 text-cyan-200 dot-cyan', 00011: completed: 'border-cyan-400/30 bg-cyan-400/10 text-cyan-200 dot-cyan', 00012: queued: 'border-slate-600 bg-slate-800/60 text-slate-400 dot-slate', 00013: draft: 'border-slate-600 bg-slate-800/60 text-slate-400 dot-slate', 00014: not_checked: 'border-slate-600 bg-slate-800/60 text-slate-400 dot-slate', 00015: not_connected: 'border-slate-600 bg-slate-800/60 text-slate-400 dot-slate' 00016: }; 00017: const dotColor = { FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/components/app/AppShell.jsx 00092: const root = document.documentElement; 00093: root.classList.toggle('reduced-motion', !!user?.reducedMotion); 00094: root.classList.toggle('high-contrast', !!user?.highContrast); 00095: }, [user?.reducedMotion, user?.highContrast]); 00096: 00097: const geoTone = settings?.geometryServiceStatus === 'connected' ? 'ok' : settings?.geometryServiceStatus === 'simulation_only' ? 'sim' : 'idle'; 00098: const geoVal = settings?.geometryServiceStatus === 'connected' ? 'Online' : settings?.geometryServiceStatus === 'simulation_only' ? 'Simulation' : 'Offline'; 00099: const geoCls = geoTone === 'ok' ? 'text-emerald-300' : geoTone === 'sim' ? 'text-violet-300' : 'text-slate-400'; 00100: const vaultTone = settings?.shireVaultStatus === 'connected' && settings?.shireVaultWritable ? 'ok' : 'warn'; 00101: const vaultVal = settings?.shireVaultStatus === 'connected' ? (settings?.shireVaultWritable ? 'Synced' : 'Read-only') : 'Not mounted'; 00102: const vaultCls = vaultTone === 'ok' ? 'text-emerald-300' : 'text-amber-300'; 00103: 00104: const railW = collapsed ? 'lg:w-[68px]' : 'lg:w-[232px]'; 00105: const mainL = collapsed ? 'lg:ml-[68px]' : 'lg:ml-[232px]'; FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/components/app/WorkflowStrip.jsx 00021: 00022: function stateFor(i, current, projectStage, validation) { 00023: if (i === 6 && validation) { 00024: if (validation === 'fail') return 'fail'; 00025: if (validation === 'warning') return 'warn'; 00026: if (validation === 'simulation_only') return 'sim'; 00027: } 00028: if (i < projectStage) return 'complete'; 00029: if (i === current) return 'current'; 00030: if (i < current) return 'complete'; 00031: return 'upcoming'; 00032: } 00033: FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/src/components/app/Help.jsx 00016: ['Check my design', 'We check your design is ready. Real 3D geometry and printing checks are confirmed by the Geometry Engine.'], 00017: ['Submit for real 3D', 'When everything passes, submit for real 3D processing and export to SHiRE storage.'] 00018: ] 00019: : [ 00020: ['Cover → Input → Concept', 'Select a validated cover, choose an input method, optionally generate concepts.'], 00021: ['Artwork & geometry', 'Sketch-to-3D runs a genuine Canvas pixel pipeline; the Studio applies projection overlays (simulation).'], 00022: ['Validation', 'Preview checks separated from real geometry/safety checks; no preview means approved.'], 00023: ['Processing & export', 'Submit preview simulations or final processing (requires live engine + writable SHiREVault).'] 00024: ]; 00025: 00026: return ( 00027: <> 00028: 00029: 00030: ... 00042: ))} 00043:
00044: 00045:
00046:

Preview vs real geometry

00047:

On-screen previews are simulations. The final printable shape, wall/mesh/clearance checks, and export are produced by the live LimbForge Geometry Engine and SHiRE storage — never by the browser.

00048:
00049: 00050:
00051: setOpen(false)} className="chip">Start a design 00052: setOpen(false)} className="chip">Processing 00053: setOpen(false)} className="chip">Settings & accessibility 00054:
FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/base44/entities/ValidationReport.jsonc 00010: "enum": [ 00011: "not_checked", 00012: "pass", 00013: "warning", 00014: "fail", 00015: "simulation_only" 00016: ] 00017: }, 00018: "checks": { 00019: "type": "array", 00020: "items": { 00021: "type": "object" 00022: } FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/base44/entities/CoverCanvasProject.jsonc 00064: "enum": [ 00065: "not_checked", 00066: "pass", 00067: "warning", 00068: "fail", 00069: "simulation_only" 00070: ] 00071: }, 00072: "finalExportReference": { 00073: "type": "string" 00074: }, 00075: "shireVaultPath": { 00076: "type": "string" FILE: /home/shire3d/ARMOR/agents/apps/covercanvas/base44/entities/GeometryJob.jsonc 00028: "type": "object" 00029: }, 00030: "errorMessage": { 00031: "type": "string" 00032: }, 00033: "simulation": { 00034: "type": "boolean", 00035: "default": false 00036: }, 00037: "startedDate": { 00038: "type": "string", 00039: "format": "date-time" 00040: }, FILE: /home/shire3d/ARMOR/services/cadquery_engine_service.py 00013: FORGE_SRC = FORGE_ROOT / "src" 00014: WRAPPER = Path(os.environ.get("SHIRE_CADQUERY_PYTHON", "/home/ray/.local/bin/shire-cadquery-python")) 00015: ADAPTER_MODULE = "shireforge.forge_engine.academy_practice_adapter" 00016: ADAPTER_PATH = FORGE_SRC / "shireforge" / "forge_engine" / "academy_practice_adapter.py" 00017: SKILL_ID_RE = re.compile(r"^[a-z0-9_]+\.[a-z0-9][a-z0-9-]+$") 00018: CADQUERY_SUPPORTED_SKILLS = frozenset(['geometry_foundations.sketch-constraints', 'geometry_foundations.profiles-and-regions', 'geometry_foundations.extrusion', 'geometry_foundations.boolean-operations', 'geometry_foundations.fillets', 'geometry_foundations.chamfers', 'geometry_foundations.solid-topology', 'geometry_foundations.symmetry', 'geometry_foundations.patterning', 'geometry_foundations.bounding-envelopes', 'geometry_foundations.geometric-tolerances', 'parametric_cad.parameter-architecture', 'parametric_cad.derived-parameters', 'parametric_cad.cadquery-workplanes', 'parametric_cad.cadquery-selectors', 'parametric_cad.cadquery-solids', 'parametric_cad.cadquery-exporters', 'parametric_cad.constraint-driven-features', 'parametric_cad.configuration-families', 'parametric_cad.step-export', 'parametric_cad.parametric-test-matrices', 'parametric_cad.cad-script-documentation', 'validation_and_simulation.geometry-integrity', 'validation_and_simulation.parameter-boundaries', 'validation_and_simulation.mass-and-volume', 'validation_and_simulation.regression-testing', 'validation_and_simulation.evidence-packaging', 'validation_and_simulation.release-gates']) 00019: 00020: 00021: class CadQueryEngineService: 00022: """Subprocess bridge from ARMOR into the isolated SHiREForge CadQuery engine.""" 00023: 00024: def __init__(self) -> None: 00025: self._status_cache: dict[str, Any] | None = None FILE: /home/shire3d/ARMOR/services/design_academy_practice_service.py 00052: "geometry_foundations", 00053: "parametric_cad", 00054: "mesh_and_sculpting", 00055: "rendering_and_communication", 00056: "product_aesthetics", 00057: "validation_and_simulation", 00058: } 00059: 00060: PHYSICAL_EVIDENCE_DOMAINS = { 00061: "additive_manufacturing", 00062: "materials_and_processes", 00063: "assemblies_and_mechanisms", 00064: "enclosures_and_mounts", ... 00313: return "cadquery_candidate" 00314: if skill_id.startswith("mesh_and_sculpting."): 00315: return "native_mesh_pipeline" 00316: if skill_id.startswith("rendering_and_communication."): 00317: return "native_render_pipeline" 00318: if skill_id.startswith("validation_and_simulation."): 00319: return "geometry_validation_adapter" 00320: return None 00321: 00322: def _initial_record(self, item: dict[str, Any]) -> dict[str, Any]: 00323: skill_id = str(item["skill_id"]) 00324: paths = self._skill_paths(skill_id) 00325: manifest = _load_json(paths["manifest"], {}) FILE: /home/shire3d/ARMOR/services/forge_learning_service.py 02023: "- RUN HEADLESS BLENDER RUN BHR-XXXX [currently blocked]\n\n" 02024: "Later roadmap:\n" 02025: "- Approval-gated background Blender dry-run.\n" 02026: "- Job log and result report.\n" 02027: "- View STLs button on ARMOR OS homescreen.\n" 02028: "- Approval-gated STL export queue." 02029: ) 02030: 02031: def create_headless_blender_run_request(self, plan_id): 02032: import json 02033: from datetime import datetime 02034: from pathlib import Path 02035: ... 03267: "- Model generation used: NO", 03268: "- Autonomous queue used: NO", 03269: "", 03270: "Next safe roadmap:", 03271: "- Add View STLs button as read-only folder viewer.", 03272: "- Add approval-gated STL export later.", 03273: "- Keep Ray approval on all generation work.", 03274: "", 03275: ] 03276: 03277: (job_dir / "README.md").write_text("\n".join(report_lines), encoding="utf-8") 03278: (job_dir / "result_report.md").write_text("\n".join(report_lines), encoding="utf-8") 03279: (job_dir / "manifest.json").write_text(json.dumps(job, indent=2) + "\n", encoding="utf-8") FILE: /home/shire3d/ARMOR/services/wake_word_service.py 00001: """SHIRE dormant wake-word controller. 00002: 00003: Simulation-only candidate for SHIRE-VOICE-0002. 00004: 00005: This module cannot open a microphone, execute PocketSphinx, retain audio, 00006: use a network, play sound, or alter system state. 00007: """ 00008: 00009: from enum import Enum 00010: from time import monotonic ... 00054: def __init__( 00055: self, 00056: privacy_snapshot, 00057: on_listening: Optional[Callable[[], None]] = None, 00058: on_idle: Optional[Callable[[], None]] = None, 00059: simulation_mode: bool = False, 00060: ) -> None: 00061: self.privacy_snapshot = privacy_snapshot 00062: self.on_listening = on_listening 00063: self.on_idle = on_idle 00064: self.simulation_mode = bool(simulation_mode) 00065: self.state = WakeWordState.DISABLED 00066: self.last_error = "" 00067: self._last_detection_at: Optional[float] = None 00068: 00069: @staticmethod 00070: def normalize_phrase(phrase: str) -> str: 00071: return " ".join(str(phrase).strip().lower().split()) ... 00136: getattr(snapshot, "enrolled_speaker_count", 0) 00137: ) > 0 00138: ) 00139: 00140: def arm(self) -> bool: 00141: if self.simulation_mode: 00142: self.state = WakeWordState.ARMED 00143: self.last_error = "" 00144: return True 00145: 00146: if not self._live_policy_authorized(): 00147: self.state = WakeWordState.DISABLED 00148: self.last_error = ( ... 00157: def simulate_detection( 00158: self, 00159: phrase: str, 00160: detected_at: Optional[float] = None, 00161: ) -> bool: 00162: if not self.simulation_mode: 00163: self.last_error = ( 00164: "Simulated detection requires simulation mode." 00165: ) 00166: return False 00167: 00168: if self.state != WakeWordState.ARMED: 00169: self.last_error = "Controller is not armed." 00170: return False 00171: FILE: /home/shire3d/ARMOR/services/blender_mastery_state.py 00024: "export": ("export_request",), 00025: } 00026: 00027: # Changing an approved artifact invalidates that approval and every approval 00028: # downstream from it. Adding a new downstream artifact must not invalidate an 00029: # unchanged upstream approval (for example, an export request must preserve the 00030: # final-model approval on which it depends). 00031: INVALIDATION_SCOPES = { 00032: "design_brief": ("design", "blockout", "final", "export"), 00033: "concept_sketch": ("design", "blockout", "final", "export"), 00034: "blockout_model": ("blockout", "final", "export"), 00035: "blockout_previews": ("blockout", "final", "export"), 00036: "blockout_report": ("blockout", "final", "export"), ... 00064: 00065: APPROVAL_STAGE = { 00066: "design": ("AWAITING_DESIGN_APPROVAL", "DESIGN_APPROVED"), 00067: "blockout": ("AWAITING_BLOCKOUT_APPROVAL", "BLOCKOUT_APPROVED"), 00068: "final": ("AWAITING_FINAL_APPROVAL", "FINAL_APPROVED"), 00069: "export": ("AWAITING_EXPORT_APPROVAL", "EXPORT_APPROVED"), 00070: } 00071: 00072: 00073: class MasteryError(ValueError): 00074: """Base error for rejected state-machine operations.""" 00075: 00076: ... 00311: missing = [kind for kind in required if kind not in project["artifacts"]] 00312: if missing: 00313: raise ApprovalError("missing required artifacts: " + ", ".join(missing)) 00314: 00315: if scope == "export" and not approval_active(project, "final"): 00316: raise ApprovalError("active final-model approval is required before export approval") 00317: 00318: return { 00319: "project_id": project["project_id"], 00320: "scope": scope, 00321: "artifacts": { 00322: kind: { 00323: "revision": project["artifacts"][kind]["revision"], FILE: /home/shire3d/ARMOR/services/covercanvas-adaptive-relief/curved_relief_worker.py 00372: 00373: report.update( 00374: { 00375: "engine_version": "0.2.0", 00376: "geometry_type": "curved_layered_relief_proof", 00377: "simulation": False, 00378: "real_geometry_generated": True, 00379: "patient_specific": False, 00380: "validated_cover": False, 00381: "manufacturing_ready": False, 00382: "export_allowed": False, 00383: "nominal_shell_thickness_mm": 2.5, 00384: "maximum_relief_mm": 2.8, FILE: /home/shire3d/ARMOR/services/covercanvas-adaptive-relief/engine.py 00100: 00101: return { 00102: "service": CONFIG["service_name"], 00103: "service_version": CONFIG["service_version"], 00104: "real_service": True, 00105: "simulation": False, 00106: "programs": programs, 00107: "python_modules": modules, 00108: "stages": { 00109: "request_validation": True, 00110: "persistent_jobs": True, 00111: "capability_detection": True, 00112: "cover_mesh_loading": real_mesh_candidate, ... 00118: "stl_export": False, 00119: "three_mf_export": False, 00120: "step_export": False, 00121: "manufacturing_export": False 00122: }, 00123: "manufacturing_export_blocked": True, 00124: "safety": CONFIG["safety"] 00125: } 00126: 00127: 00128: def sha256_json(value: Any) -> str: 00129: encoded = json.dumps( 00130: value, ... 00323: status="blocked", 00324: progress=100, 00325: stage="request_rejected", 00326: errors=errors, 00327: manufacturing_ready=False, 00328: simulation=False, 00329: ) 00330: return 00331: 00332: update_job( 00333: job_id, 00334: progress=35, 00335: stage="capability_check", ... 00352: status="blocked", 00353: progress=100, 00354: stage="mesh_engine_not_installed", 00355: result={ 00356: "real_service": True, 00357: "simulation": False, 00358: "request_validated": True, 00359: "geometry_generated": False, 00360: "manufacturing_ready": False, 00361: "export_allowed": False, 00362: "next_required_stage": "adaptive_surface_wrap_v0.2", 00363: "message": ( 00364: "The native engine accepted and validated this job. " 00365: "Adaptive mesh wrapping is not enabled in v0.1, so export remains blocked." 00366: ), 00367: }, 00368: manufacturing_ready=False, 00369: simulation=False, 00370: ) 00371: except Exception as exc: 00372: update_job( 00373: job_id, 00374: status="failed", 00375: progress=100, 00376: stage="engine_error", 00377: error=str(exc), 00378: traceback=traceback.format_exc(), 00379: manufacturing_ready=False, 00380: simulation=False, 00381: ) 00382: 00383: 00384: def create_job(payload: dict[str, Any]) -> dict[str, Any]: 00385: job_id = ( 00386: f"cc-{datetime.now(timezone.utc).strftime('%Y%m%d%H%M%S')}-" 00387: f"{uuid.uuid4().hex[:10]}" ... 00392: "created_at": utc_now(), 00393: "updated_at": utc_now(), 00394: "status": "queued", 00395: "progress": 0, 00396: "stage": "queued", 00397: "simulation": False, 00398: "manufacturing_ready": False, 00399: "request_sha256": sha256_json(payload), 00400: "request": payload, 00401: } 00402: write_job(job) 00403: 00404: worker = threading.Thread(target=process_job, args=(job_id,), daemon=True) ... 00456: "ok": True, 00457: "status": "ready", 00458: "service": CONFIG["service_name"], 00459: "service_version": CONFIG["service_version"], 00460: "real_service": True, 00461: "simulation": False, 00462: "manufacturing_export_blocked": True, 00463: "time": utc_now(), 00464: }, 00465: ) 00466: return 00467: 00468: if path == "/capabilities": 00469: self.send_json(200, {"ok": True, **capabilities()}) ... 00497: { 00498: "ok": not errors, 00499: "valid": not errors, 00500: "errors": errors, 00501: "real_service": True, 00502: "simulation": False, 00503: "manufacturing_ready": False, 00504: }, 00505: ) 00506: return 00507: 00508: if path == "/jobs": 00509: job = create_job(payload) 00510: self.send_json( 00511: 202, 00512: { 00513: "ok": True, 00514: "simulation": False, 00515: "real_service": True, 00516: "job_id": job["id"], 00517: "status": job["status"], 00518: "progress": job["progress"], 00519: "manufacturing_ready": False, 00520: }, 00521: ) FILE: /home/shire3d/ARMOR/data/agents/covercanvas/runtime/relief-engine/jobs/cc-20260803130032-519c689920.json 00004: "created_at": "2026-08-03T13:00:32.106679Z", 00005: "updated_at": "2026-08-03T13:00:32.539795Z", 00006: "status": "blocked", 00007: "progress": 100, 00008: "stage": "mesh_engine_not_installed", 00009: "simulation": false, 00010: "manufacturing_ready": false, 00011: "request_sha256": "abdd9ce93cf8797af71271cbba9110dcb2ecabc1ef02b1228929afbc632dbdca", 00012: "request": { 00013: "project_id": "engine-v0.1-test", 00014: "simulation": false, 00015: "cover_model": { 00016: "reference": "/tmp/test-cover.stl", 00017: "id": "cover-test", 00018: "name": "Engine Contract Test", 00019: "limb_type": "below_knee", 00020: "side": "right", 00021: "source_format": "stl", ... 00067: }, 00068: "capabilities": { 00069: "service": "SHiRE CoverCanvas Adaptive Relief Engine", 00070: "service_version": "0.1.0", 00071: "real_service": true, 00072: "simulation": false, 00073: "programs": { 00074: "blender": { 00075: "available": true, 00076: "path": "/usr/bin/blender", 00077: "version": "Blender 4.0.2" 00078: }, 00079: "openscad": { ... 00128: "stl_export": false, 00129: "three_mf_export": false, 00130: "step_export": false, 00131: "manufacturing_export": false 00132: }, 00133: "manufacturing_export_blocked": true, 00134: "safety": { 00135: "allow_manufacturing_export": false, 00136: "require_validated_cover": true, 00137: "require_protected_zone_check": true, 00138: "minimum_wall_thickness_mm": 2.0, 00139: "minimum_raised_feature_mm": 0.6, 00140: "minimum_recessed_feature_mm": 0.6, ... 00143: } 00144: }, 00145: "normalised_request_sha256": "abdd9ce93cf8797af71271cbba9110dcb2ecabc1ef02b1228929afbc632dbdca", 00146: "result": { 00147: "real_service": true, 00148: "simulation": false, 00149: "request_validated": true, 00150: "geometry_generated": false, 00151: "manufacturing_ready": false, 00152: "export_allowed": false, 00153: "next_required_stage": "adaptive_surface_wrap_v0.2", 00154: "message": "The native engine accepted and validated this job. Adaptive mesh wrapping is not enabled in v0.1, so export remains blocked." 00155: } FILE: /home/shire3d/ARMOR/data/agents/covercanvas/runtime/relief-engine/outputs/curved-relief-proof-20260803T130334Z/mesh-report.json 00012: "y": 67.91204698862083, 00013: "z": 280.0 00014: }, 00015: "engine_version": "0.2.0", 00016: "geometry_type": "curved_layered_relief_proof", 00017: "simulation": false, 00018: "real_geometry_generated": true, 00019: "patient_specific": false, 00020: "validated_cover": false, 00021: "manufacturing_ready": false, 00022: "export_allowed": false, 00023: "nominal_shell_thickness_mm": 2.5, 00024: "maximum_relief_mm": 2.8,