Thursday, 12 February 2026

PROMPT: Platform-grade MVPL Calculator

 Here is the prompt generated by ChatGPT to create from scratch a more mature, platform-grade MVPL-approach calculator HTML app. In the next post I give ChatGPT’s own assessment of the resulting extensible core. 


✅ MASTER PRODUCTION PROMPT

MVPL Modular Calculator Platform Generator


SYSTEM ROLE

You are Codex.

You are generating a fully working MVPL Modular Calculator Platform.


PROJECT TITLE

MVPL Modular Calculator Core with Profile-Driven Extension Platform


GLOBAL OBJECTIVE

Generate a complete modular calculator web application platform that includes:

  1. MVPL Architecture
  2. Stable arithmetic calculator core
  3. Slot-based keypad UI
  4. Multi-profile customer configuration
  5. Profile-driven extension activation controller
  6. Full extension lifecycle management
  7. Dependency-aware extension registry
  8. Built-in InverseExtension
  9. Developer diagnostic panel


OUTPUT REQUIREMENTS

Generate EXACTLY TWO FILES:


index.html

inverse.js

Both must be fully functional and compatible.

Do NOT include explanations outside code comments.


GLOBAL TECHNICAL CONSTRAINTS

• Single file HTML core
• All core CSS + JS embedded in index.html
• inverse.js must be standalone
• No external libraries
• Must work offline
• Must work on iPad Safari / Textastic
• Must follow MVPL architecture
• No eval or unsafe execution
• extensionAPI must be globally exposed
• Extensions must never modify core globals
• All extension state must be namespaced per profile


NON-REGRESSION GUARANTEES

The following MUST NEVER BREAK:

• Calculator arithmetic correctness
• Display behavior
• Slot keypad structure
• UI zone architecture
• Existing extension compatibility
• Profile state isolation
• Lifecycle hook reliability
• Backwards compatibility for legacy extensions

If any rule conflicts, prioritize preserving backward compatibility and Stage 0 stability.


MVPL ARCHITECTURE SPECIFICATION


MODEL LAYER

Profiles


profiles = {

  profileKey: {

    name: string,

    layout: string,

    enabledExtensions: string[],

    state: object

  }

}

Rules:

• Profiles isolate extension state
• Extension state stored at:


profiles[currentProfile].state[extensionName]

• Switching profile switches namespace
• Profiles auto apply layout presets


VIEW LAYER

UI Zones

Must implement:


topbar

display

mainpad

sidebar

footer

statusbar

Extensions must be able to inject UI into zones.


SLOT-BASED KEYPAD SYSTEM

Each keypad location must use fixed slot containers:


slot-clear

slot-cancel

slot-divide

slot-multiply

slot-minus

slot-plus

slot-equals

slot-0 through slot-9

slot-decimal

slot-extension-1

slot-extension-2

Rules:

• Core buttons must never shift
• Extensions may only insert into extension slots


PRESENTER LAYER

Extension API

Lifecycle Controller

Layout Manager


STAGE 0 — CALCULATOR CORE

Must implement:

• Display
• 0-9 numeric buttons
• Decimal
• + − × ÷
• Equals
• Clear
• Backspace

Layout:

• CSS Grid
• Responsive
• Touch friendly
• Modern minimal styling
• High contrast


STAGE 1 — PROFILE MODEL & ENABLEMENT

Create three profiles:


default

scientific

education

Rules:

• Each profile must define enabledExtensions array
• Switching profiles must re-evaluate extension activation
• Extension state must persist per profile


STAGE 2 — EXTENSION SYSTEM


Extension Manifest Format


{

  name: string,

  version: string,

  description: string,

  dependencies?: string[],

  priority?: number,

  stateSchema?: object,

  onInit(api, state),

  onProfileSwitch(api, state),

  onLayoutChange(api, state),

  onDestroy(api, state),

  init?(api)   // backward compatibility

}


EXTENSION REGISTRY

Must support:

• registerExtension(manifest)
• Dependency resolution
• Priority load ordering
• Conflict detection
• Safe partial loading
• Registry storage without immediate activation


EXTENSION ACTIVATION CONTROLLER (AUTHORITATIVE MODEL)

Create centralized function:


evaluateActiveExtensions(triggerType)

This controller MUST:

Activation

• Activate extensions that:

  • Are registered
  • Are enabled in profile
  • Are not already active

Deactivation

• Destroy extensions removed from enabledExtensions

Lifecycle Execution

• onInit
• onProfileSwitch
• onLayoutChange
• onDestroy
• legacy init()

Safety

• Prevent duplicate UI insertion
• Resolve dependency order
• Fail gracefully if hooks missing


SAFE EXTENSION REMOVAL REQUIREMENTS

Destroying an extension MUST:

• Remove extension UI
• Preserve profile state
• Not affect other extensions
• Not break core calculator


EXTENSION API CONTRACT

The API object provided to extensions MUST expose:


addUIComponent({ zone, element })

addButton(slotName, element)

removeUIComponent(element)


getDisplayValue()

setDisplayValue(value)


getProfile()


state()    // returns namespaced profile state


subscribeLayoutChanges(callback)


BACKWARD COMPATIBILITY RULES

Extensions that only implement:


init(api)

must still function.

Extensions missing lifecycle hooks must not crash.


STAGE 3 — LAYOUT PRESETS

Implement:


minimal

scientific

education

Profiles automatically apply presets.

Layout changes must trigger:


onLayoutChange


DEVELOPER STATUS PANEL

Status panel must display:

• Active profile
• Active extensions
• Extension load warnings or errors
• Load ordering


EXTENSION SAFETY RULES

Extensions must:

• Only use extensionAPI
• Only store state inside profile namespace
• Never modify core variables
• Use slot system for UI insertion


BUILT-IN EXTENSION SPECIFICATION

FILE: inverse.js

Extension Name:


InverseExtension


Functional Behavior

• Adds button labeled 1/x
• Computes multiplicative inverse of display value


PROFILE RESTRICTION

The 1/x button:

• MUST only appear in scientific profile
• MUST be removed in other profiles
• MUST only function in scientific profile


UI RULES

• Must insert using extension slot
• Must not replace core buttons


ERROR HANDLING

• Divide by zero → display "Error"
• Invalid numeric input → display "Error"


STATE SCHEMA


{

  lastUsed: null

}


REQUIRED LIFECYCLE SUPPORT

InverseExtension must implement:


onInit

onProfileSwitch

onLayoutChange

onDestroy


DOCUMENTATION REQUIREMENTS

Inside code include teaching comments describing:

• MVPL architecture
• Extension lifecycle
• Slot keypad system
• Profile enablement model
• Namespaced state explanation
• Why activation controller exists


ACCEPTANCE CRITERIA

System is complete ONLY if:

✔ Arithmetic works
✔ Profiles switch correctly
✔ Extension activation follows enabledExtensions
✔ Inverse button appears only in scientific profile
✔ Extension state persists per profile
✔ No core buttons move
✔ Dependencies load in order
✔ Developer panel shows active extensions
✔ Legacy extensions remain compatible


TESTING INSTRUCTIONS (inside code comments)

Include instructions for:

• Running in Safari / Textastic
• Switching profiles
• Confirming extension activation / removal
• Confirming lifecycle hook firing
• Verifying calculator operations


OUTPUT FORMAT (STRICT)

Return EXACTLY:


----- index.html -----

<full code>


----- inverse.js -----

<full code>

No summaries
No explanations
Only code output


FINAL AUTHORITATIVE RULE

If any instruction conflicts:

  1. Preserve calculator core stability
  2. Preserve backward compatibility
  3. Preserve profile state isolation
  4. Preserve extension lifecycle correctness


✅ END MASTER PROMPT


No comments:

Post a Comment