Status: Implemented architecture with future consumer integration work
Project: web.template
The fundamental architecture is:
Application --> Template --> Core
The current ownership model is:
- Core contains reusable technical capabilities.
- Template contains the reusable application platform.
- Standard Agent.Workbench functionality belongs to Template.
- Application contains concrete product composition and extensions.
- HEMS is an example of a concrete Application.
- The current
src/application/directory is the in-repository Agent.Workbench Application composition. - Template must not import a concrete Application.
- Core must remain independent from both Template and Application.
Agent.Workbench is the current in-repository Application identity/composition, but it is not modeled as a separate consumer Application repository
A separate Agent.Workbench Application repository is therefore not required.
The implemented dependency direction is:
Concrete Application
|
v
Base Template
|
v
Core
In short:
Application --> Template --> Core
The following dependency directions are not allowed:
Template --> concrete Application
Core --> Template
Core --> Application
Template may depend on Core.
Application may consume supported Template and Core integration surfaces.
The dependency direction must not be reversed.
The Base Template provides the reusable application platform.
It includes responsibilities such as:
Base Template
|
+-- TemplateApp
+-- createTemplateApp
+-- ApplicationConfig
+-- ApplicationConfigContext
+-- configuration infrastructure
+-- navigation infrastructure
+-- Template navigation definitions
+-- Template screen registry
+-- Redux infrastructure
+-- Agent.Workbench standard functionality
+-- Agent.Workbench state
+-- authentication and session orchestration
+-- server selection
+-- settings
+-- design system
+-- notifications
+-- update orchestration
+-- reusable screens
+-- reusable hooks
+-- reusable components
+-- layout
+-- Core integration
Standard Agent.Workbench functionality is intentionally part of this reusable platform.
Examples include:
Program Start
Data Analyzing
Database configuration
Server configuration
Live Console
Settings
Agent.Workbench state
Agent.Workbench navigation
Agent.Workbench API integration where reusable
These responsibilities are not considered transitional Application code.
A concrete Application provides product-specific composition on top of the Base Template.
Examples of Application-owned responsibilities include:
Application
|
+-- Application identity
+-- Application metadata
+-- Template feature selection
+-- Application-specific navigation
+-- Application-specific screens
+-- Application translations
+-- optional Application-specific Redux state
+-- product-specific behavior
+-- product-specific branding
+-- product-specific build configuration
+-- product-specific deployment configuration
HEMS is an example of a concrete Application.
Conceptually:
HEMS Application
|
v
Base Template
|
v
Core
The current repository uses the in-repository Agent.Workbench Application composition to validate this contract before a separate consumer such as HEMS is integrated.
The current web.template repository contains:
web.template
|
+-- src/core/
|
+-- src/template/
|
+-- src/application/
The responsibility mapping is:
src/core/
reusable technical capabilities
src/template/
reusable Base Template platform
including Agent.Workbench standard functionality
src/application/
Agent.Workbench Application composition
used to validate the Application integration contract
src/application/ is not Agent.Workbench.
Concrete products may consume the Base Template from their own repositories.
The expected model is:
web.template
Base Template
^
|
+--------+--------+
| |
HEMS future Applications
A future HEMS repository may own:
HEMS configuration
HEMS navigation extensions
HEMS screens
HEMS translations
optional HEMS-specific Redux state
HEMS business logic
HEMS branding
HEMS build configuration
HEMS deployment configuration
There is no equivalent required Agent.Workbench Application repository because Agent.Workbench standard functionality is part of the Base Template.
Developer-facing Application configuration must remain simple.
Developers should not need to edit TypeScript, TSX, JavaScript or JSON files for normal Application configuration.
The current configuration structure is:
src/application/config/
├── application.properties
├── features.properties
└── navigation.properties
Their responsibilities are:
application.properties
Application identity and metadata
features.properties
semantic activation or deactivation
of reusable Template features
navigation.properties
Application-specific navigation extensions
Generated TypeScript may exist as build/runtime output.
It is not the developer-facing configuration format.
The following old configuration names are not part of the current architecture:
menu.properties
tabs.properties
featureFlags.properties
menuFeatureFlags.properties
tabFeatureFlags.properties
They must not be documented as current or planned configuration.
The active model is:
application.properties
features.properties
navigation.properties
Application identity and metadata are defined through:
src/application/config/application.properties
Application identity belongs to the concrete Application.
Typical runtime identity values include:
id
displayName
Template may consume the values it requires through the formal Application contract.
Template must not rely on hardcoded product-specific identity values.
Additional metadata should only be mapped into ApplicationConfig when Template actually requires it.
Reusable Template functionality is enabled or disabled through:
src/application/config/features.properties
Examples include:
feature.notifications.enabled=true
feature.appearance.enabled=true
feature.serverSettings.enabled=true
feature.liveConsole.enabled=true
feature.programStart.enabled=true
feature.dataAnalyzing.enabled=true
feature.database.general.enabled=trueThe Application selects reusable capabilities.
Template owns their internal implementation.
This means the Application does not need to configure internal Template details such as:
numeric menu IDs
internal parent IDs
Template screen registry keys
authentication visibility rules
runtime visibility rules
Agent.Workbench internal navigation definitions
Application-specific navigation extensions are configured through:
src/application/config/navigation.properties
Example:
menu.example.enabled=true
menu.example.caption=exampleApplication
menu.example.parent=settings
menu.example.position=99
menu.example.screen=example-screenThe Application describes its own navigation extension semantically.
Template remains responsible for reusable navigation infrastructure and reusable Template navigation definitions.
Custom Application IDs are generated or resolved internally.
Application developers do not manually maintain Template internal numeric IDs.
Navigation is separated by responsibility.
menu rendering
menu tree construction
routing
path calculation
Template navigation definitions
Template screen registry
Template visibility integration
Agent.Workbench navigation
Template menu ordering
Application-specific navigation extensions
Application-specific screen references
optional custom menu ordering
The composition is:
Template navigation
+
Application navigation extensions
|
v
runtime navigation
Applications do not provide or duplicate the complete Base Template navigation structure.
Normal Template menu ordering is derived automatically from sibling order in the Template menu catalog.
Template menu definitions therefore do not require manually maintained numeric positions in normal cases.
Application custom position remains optional.
For items without an explicit position, MenuHub uses:
Number.MAX_SAFE_INTEGERThe relevant implementation is:
src/template/screens/menu/MenuHubScreen.tsx
This keeps Drawer and MenuHub ordering consistent.
Developer-facing .properties files are transformed into runtime configuration.
Conceptually:
Application .properties
|
v
Template configuration tooling
|
v
generated runtime artifacts
|
v
Application composition
|
v
Base Template
The configuration tooling exists under:
src/template/config/build/
A central generator is:
generateApplicationConfig.mjs
Generated Application artifacts are written under:
src/application/generated/
The explicit generation command is:
npm run config:generateGenerated TypeScript should not be manually used as the normal developer configuration surface.
Application-owned screens are discovered automatically.
The discovery implementation exists at:
src/template/config/build/applicationScreenDiscovery.mjs
Examples:
ExampleScreen.tsx
-> example-screen
ExampleScreen2.tsx
-> example-screen2
HemsOverviewScreen.tsx
-> hems-overview-screen
The generated registry is:
src/application/generated/applicationScreenRegistry.generated.ts
The current Agent.Workbench Application composition contains:
src/application/screens/ExampleScreen.tsx
Applications therefore do not need to manually register concrete screens inside Template.
Template must not import concrete Application screen implementations.
The reusable Template integration layer exists under:
src/template/application/
├── ApplicationConfig.ts
├── ApplicationConfigContext.tsx
├── createTemplateApp.tsx
└── TemplateApp.tsx
Defines the typed runtime contract between a concrete Application and Template.
Template owns the contract.
Application supplies concrete values.
Provides selected Application configuration values to reusable Template UI.
This avoids direct imports from concrete Application implementation.
Provides the reusable composition point.
Conceptually:
Application
|
v
createTemplateApp(...)
|
v
TemplateApp
Provides the reusable React application shell.
It may integrate reusable responsibilities such as:
providers
navigation
session handling
application layout
dialogs
notifications
update watchers
developer tooling
state integration
Application is the composition root.
The direction is:
Application configuration
|
v
Application
|
v
createTemplateApp(...)
|
v
TemplateApp
Template does not select which concrete Application is running.
The architecture intentionally avoids:
Template
|
+-- if HEMS ...
+-- if Product A ...
+-- if Product B ...
Each concrete consumer composes itself with the Base Template.
Agent.Workbench must not be treated as a concrete Application for runtime selection.
Incorrect:
Template
|
+-- detect Agent.Workbench
+-- detect HEMS
+-- choose product
Correct:
Base Template
|
+-- Agent.Workbench standard functionality
HEMS Application
|
v
Base Template
Agent.Workbench does not require a separate Application resolver or Application repository under the current architecture.
Redux is a state-management technology, not an architectural layer.
State belongs to the layer that owns the corresponding responsibility.
The ownership rule is:
Reusable Template state
-> Template
Agent.Workbench standard state
-> Template
Concrete product-only state
-> Application
Template provides reusable Redux infrastructure.
Applications may optionally provide their own reducers.
Agent.Workbench state is intentionally Template-owned.
A dedicated area exists at:
src/template/state/agent-workbench/
This state is not transitional Application state.
It must not be documented as waiting to move into a separate Agent.Workbench repository.
Standard Agent.Workbench reducers belong to the same architectural layer as the standard Agent.Workbench functionality they support.
Concrete Applications may provide their own Redux state when required.
The current extension point is:
src/application/state/applicationReducers.ts
The current Agent.Workbench Application composition does not require meaningful Application-specific Redux state.
Therefore this file is currently essentially empty.
This is valid.
It represents an optional extension point rather than unfinished extraction work.
Reusable store infrastructure exists under:
src/template/state/store/
Known infrastructure includes:
createTemplateStore.ts
rootReducer.ts
store.ts
templateReducers.ts
types.ts
useAppDispatch.ts
useAppSelector.ts
The conceptual composition is:
Template reducers
+
optional Application reducers
|
v
runtime Redux store
Template must not directly import concrete Application reducer implementations.
Application reducers must not silently replace Template-owned reducer keys.
Core contains reusable technical capabilities.
Known areas include:
src/core/
├── authentication/
├── runtime/
├── server/
└── update/
Core must not own:
React application-shell composition
Template navigation
Template UI
Agent.Workbench composition
Application configuration
concrete product behavior
The dependency constraints are:
Core -X-> Template
Core -X-> Application
Authentication is separated by responsibility.
Core
├── technical authentication capabilities
├── JWT helpers
├── transport/interceptor logic
└── technical logout guards
Template
├── authentication UI
├── session orchestration
└── reusable login/session behavior
Application
└── concrete product configuration where required
This follows:
Application --> Template --> Core
Server functionality is also separated by responsibility.
Core
├── normalization
├── validation
├── technical server checks
├── environment detection
└── reusable backend parsing
Template
├── server selection
├── reusable server state
├── orchestration
└── UI
Application
└── product-specific server configuration where required
Update functionality follows the same architectural boundary.
Core
└── reusable technical update capabilities
Template
├── update state
├── hooks
├── watchers
├── dialogs
├── notifications
└── reusable orchestration
Application
└── product-specific update behavior only when genuinely product-specific
Reusable application UI belongs to Template.
The design system exists under:
src/template/components/design-system/
Reusable Template components also include areas such as:
developer-tools/
dynamic-content/
layout/
localization/
notifications/
rich-text-editor/
A component belongs to Application only when it is genuinely specific to that concrete product.
API ownership follows responsibility rather than names alone.
Reusable technical communication
-> Core where appropriate
Reusable Base Template / Agent.Workbench API integration
-> Template where appropriate
Concrete product business API
-> Application
Agent.Workbench API code is not automatically Application-owned merely because it contains Agent.Workbench-specific terminology.
If it supports standard Base Template Agent.Workbench functionality, Template ownership can be correct.
Concrete product branding belongs to Application when it is genuinely product-specific.
Examples include:
Application logo
product-specific assets
product identity
Reusable theme and design-system infrastructure belongs to Template.
Branding values should only be added to ApplicationConfig when Template actually needs them.
Concrete consumer repositories should own their product-specific build and deployment configuration.
For example, a future HEMS repository may own:
HEMS identity
HEMS configuration
HEMS release configuration
deployment targets
product-specific infrastructure configuration
The Base Template provides reusable platform capability and integration contracts.
The Agent.Workbench Application composition inside web.template exists primarily to validate those contracts.
Concrete consumer repositories should use explicit supported Template integration surfaces.
Preferred:
ApplicationConfig
createTemplateApp
properties-based configuration
automatic screen discovery
documented navigation extensions
documented Redux extension points
supported Template exports
Avoid:
deep imports into arbitrary Template implementation files
product-specific patches inside Template
Template imports from concrete Application folders
manual registration of Application screens inside Template
duplication of Template navigation definitions
The exact package-level public API may continue to evolve.
A future HEMS consumer should validate that the Base Template contract works outside the current in-repository Agent.Workbench Application composition.
HEMS may provide:
application.properties
features.properties
navigation.properties
HEMS screens
HEMS translations
optional HEMS-specific reducers
HEMS business logic
HEMS branding
HEMS build/deployment configuration
The Base Template continues to provide the reusable application platform and standard Agent.Workbench functionality.
This consumer integration extends the architecture.
It does not require changing Agent.Workbench ownership.
The current architecture includes:
Application --> Template --> Core
ApplicationConfig
ApplicationConfigContext
createTemplateApp
TemplateApp
application.properties
features.properties
navigation.properties
configuration generation
automatic Application screen discovery
generated Application screen registry
Agent.Workbench Application composition
Application-specific navigation extensions
Template-owned navigation internals
Template menu ordering
reusable Redux infrastructure
Agent.Workbench state in Template
optional Application reducer extension point
Core authentication/runtime/server/update areas
Template design system
standard Agent.Workbench functionality in Template
The current Agent.Workbench Application composition contains only the concrete composition required to validate the integration model.
It is not Agent.Workbench.
Its current responsibilities include:
Application configuration
ExampleScreen.tsx
generated runtime artifacts
optional Application Redux extension point
Future work may include:
HEMS consumer repository integration
Base Template consumption validation from a separate repository
public package/API refinement
consumer build and deployment setup
additional Application contract extensions when genuinely required
The previous architecture included a planned Agent.Workbench extraction phase.
That phase is no longer part of the selected architecture.
The following work is not planned under the current model:
move AgentWorkbenchOptions into an Application repository
move Agent.Workbench state into an Application repository
move Agent.Workbench menus and tabs into an Application repository
create a separate Agent.Workbench Application repository
remove standard Agent.Workbench functionality from Template
These actions would contradict the current ownership decision.
Agent.Workbench standard functionality remains Template-owned unless the architecture is explicitly changed in the future.
The following statements are no longer correct:
"The Base Template must remain independent from Agent.Workbench."
"Agent.Workbench must have its own Application repository."
"Agent.Workbench and HEMS are equivalent concrete Applications."
"Agent.Workbench state inside Template is transitional."
"Agent.Workbench screens inside Template are extraction candidates."
"Agent.Workbench reducers must move into Application."
"menu.properties will become the Application menu configuration."
"tabs.properties will become the Application tab configuration."
"menuFeatureFlags.properties will define menu features."
"tabFeatureFlags.properties will define tab features."
"Concrete Applications own the complete navigation definition."
"Template must not contain standard Agent.Workbench behavior."
The correct model is:
Agent.Workbench standard functionality
-> Base Template
HEMS
-> concrete Application
Useful dependency checks include:
git grep -n "@/application/" -- src/templateThis should remain empty because Template must not import concrete Application implementation.
Application code should use supported Template APIs instead of arbitrary Template internals.
A useful review command is:
git grep -n "@/template/" -- src/applicationUnexpected direct Template imports should be reviewed against the supported integration API.
Architecture-related changes should normally be validated with:
npm run config:generate
npx tsc --noEmit
npm test -- --runInBand
git diff --check
git status --shortConfiguration generation should run before TypeScript validation when relevant developer-facing configuration has changed.
Architecture changes should remain small and reviewable.
Recommended workflow:
- Verify current ownership.
- Verify actual source dependencies.
- Make the smallest coherent change.
- Regenerate Application configuration where required.
- Run TypeScript validation.
- Run affected tests.
- Run architecture dependency checks.
- Run
git diff --check. - Review
git status --short. - Commit a coherent completed state.
Broad automatic rewrites across unrelated files should be avoided.
The Application separation is successful when:
- Template does not import concrete Application implementation.
- Core imports neither Template nor Application code.
- Agent.Workbench standard functionality remains correctly owned by Template.
- A concrete Application can configure itself without modifying Template internals.
- A concrete Application can enable reusable Template features semantically.
- Applications do not need to know Template internal menu IDs.
- Applications can provide Application-specific navigation extensions.
- Applications can provide their own screens without Template imports.
- Application screens are automatically discovered.
- Applications can optionally provide their own Redux state.
- Agent.Workbench state remains Template-owned.
- Concrete product state does not replace Template-owned reducer keys.
- Developer-facing configuration remains properties-based.
- HEMS can consume the same Base Template through the supported contract.
- A future concrete Application can be created without changing internal Base Template implementation.
- Repository dependency boundaries remain enforceable and testable.
The current architecture is:
Application --> Template --> Core
Core provides reusable technical capabilities.
Template provides the reusable application platform.
Standard Agent.Workbench functionality belongs to Template.
The current src/application/ directory is the in-repository Agent.Workbench Application composition.
HEMS is a concrete Application.
Developer-facing Application configuration uses:
application.properties
features.properties
navigation.properties
Template owns reusable navigation implementation, internal navigation IDs, visibility rules and Agent.Workbench navigation.
Application navigation extends Template navigation instead of replacing it.
Application screens are automatically discovered.
Template owns reusable Redux infrastructure and Agent.Workbench state.
Application-specific Redux state is optional.
A separate Agent.Workbench Application repository is not part of the current architecture.
Future consumer work should validate the existing Base Template contract rather than reopen the Agent.Workbench ownership decision.