feat(dice-storage-autoconfigure): opt-in metamodel wiring - #88
Conversation
a3cb28b to
68caa2d
Compare
68caa2d to
f340946
Compare
f340946 to
2c37e41
Compare
2c37e41 to
161a549
Compare
161a549 to
3b8518c
Compare
10b9954 to
4047e0b
Compare
4047e0b to
79e332b
Compare
79e332b to
219a637
Compare
219a637 to
83a3d1e
Compare
83a3d1e to
0d1a553
Compare
23e6426 to
edce572
Compare
edce572 to
e8c5c97
Compare
|
From CODEX:
The new governance tools are exposed with generic names like run_drift_check, latest_drift_reports, and Example:
At that point the tool registry has to either reject one, overwrite one, or leave selection ambiguous. So for this PR, the practical fix is to prefix each tool explicitly, for example:
If dotted tool names are valid in the target tool registry, embabel.dice.run_drift_check is clearer. If not, use underscores. The key point is that the prefix must reach Tool.Definition.name, not only metadata or docs. There is also PR on
The configuration prefixes are repeated directly in annotations:
This is not a behavior bug, but it is easy to mistype later. Spring does not provide a class-level prefix that child private const val DICE_PREFIX = "embabel.dice" Then use those constants in @ConfigurationProperties and @ConditionalOnProperty. That keeps the public property names in one place.
The comment says _DrivineSchema is currently reported as drift, but PR 87 already added INFRASTRUCTURE_LABELS and excludes _DrivineSchema. So the comment is stale. It now tells the reader the opposite of the current behavior. |
e8c5c97 to
7edd5d7
Compare
|
On Codex items 2 and 3:
Item 1 (tool name prefixes) is answered separately. |
7edd5d7 to
5bdd94a
Compare
5bdd94a to
fc3b6b0
Compare
fc3b6b0 to
633776f
Compare
MetamodelAutoConfiguration activates only when the host declares a DeclaredSchemaSource bean — declaring your schema is the opt-in, the way providing a DataSource turns on JPA. Real @autoConfiguration with every default @ConditionalOnMissingBean so consumer beans win in either registration order; drift runner wired against the base PropositionStore port. embabel.dice.metamodel properties: enabled kill switch and drift.mode off|observe|quarantine — observe is the default, quarantine never is. Also excludes Drivine's _DrivineSchema inventory label from observed schema by verified shape. Refs #45; stacks on feat/metamodel-drift-store. Completes the metamodel train. Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
Comment and doc text only; no code change. Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
The runner is evaluate-and-report only, so ObserveOnlyDriftCheckRunner had nothing left to refuse and is gone, and DriftMode reduces to OFF and OBSERVE: off suppresses the runner bean, and no property DICE reads can move a proposition. The wiring fixes follow the reviewer's findings: the application's event listener reaches every governance collaborator that can emit a status transition, so a deliberate quarantine drives ProjectionLineageStaleCascade; Drivine-backed governance beans register only under the graph backend, so a DeclaredSchemaSource under the default in-memory backend starts cleanly; and MetamodelDiffer and DeclaredObservedDiffer resolve independently, so distinct consumer beans are both honored. Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
Drift reports, the declared version, and quarantine release were reachable only from a debugger: the report store's bounded reads had no caller and release existed as an SPI with no door. One GovernanceOperationsService now answers reads (latest reports global and per context, the current declared version), runs a check that returns the full impact a sweep would evaluate, and releases a held proposition through the recorded-prior-status path, refusing across contexts. GovernanceController exposes it under /api/v1/metamodel and GovernanceTools exposes it to agents, both following the discovery surface's shape, wired in the autoconfigure module under the governance conditions and overridable per bean. Per-report release is absent: a DriftReport carries no identity a reason could name, and that modeling belongs to its own slice. Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
AGENTS.md described a quarantine drift mode that does not exist and contradicted the autoconfiguration's override behavior; it now states OFF and OBSERVE and the metamodel catalog exception, and the operator surface entry carries the EXPERIMENTAL marker with its opt-in conditions. The observed-schema wiring adapts to the derived-ownership rework: a DiceOwnedSchema bean builds from the registered DiceStorageSchema beans, overridable per bean, and the Drivine source takes it through its constructor. Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
The controller's condition reached the opt-in only through the service bean, so a host hand-wiring GovernanceOperationsService without a declared schema got six public routes. The HTTP surface now requires the DeclaredSchemaSource bean and the enabled property itself, matching the metamodel wiring's idiom, and the condition tests enumerate resolved URLs from a live handler mapping, so a route that exists is a route the test sees. Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
Declaring a schema opts a host into versioning; it must not opt them into HTTP or agent tools. The controller now activates only through the host's explicit DiceRestConfiguration import, joining the one REST activation idiom, and the governance HTTP autoconfiguration is gone. A conditional on an imported class is answered before autoconfigured beans exist, so the import rides a lowest-precedence deferred selector, pinned by tests covering import-with-schema, import-without-schema and no-import. GovernanceTools is host-constructed the way DiscoveryTools is, so the host chooses what an agent can call. The branch's public governance types carry ApiStatus.Experimental, and the wiring doc states the deliberate narrowings: release is per proposition, and only a host call to DriftSweepCapable.sweep applies a quarantine. Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
embabel-agent-dependencies manages neither mockito-kotlin nor the JetBrains annotations, so the root pom now carries both versions and the module poms declare the artifacts without one. Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
The metamodel auto-configuration and its properties read every prefix from DicePropertyPrefixes, so the property names live in one place. Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
DrivineObservedSchemaSource keeps _DrivineSchema out of the observed types through INFRASTRUCTURE_LABELS. The test comment said the opposite, and the test now asserts the exclusion. Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
633776f to
408705f
Compare
PR 6, closing the metamodel train (#83 → #84 → #85 → #86 → #87 → #88). The governance loop becomes usable from a Spring Boot app, and it gets an operator.
MetamodelAutoConfigurationindice-storage-autoconfigureregisters only when the host declares aDeclaredSchemaSourcebean — declaring your schema is the opt-in — and then wires the loop: version store, drift-report store, observed-schema source, both differ roles, quarantine policy,DriftSweepCapable, drift runner, and the metamodelSchemaCatalog. Every wired collaborator is@ConditionalOnMissingBean.embabel.dice.metamodel.enabled=falseremoves the beans;drift.modeisofforobserve(default); backend selection followsembabel.dice.store.type. Nothing in the wiring runs a check or moves a proposition: a check happens when the host callsDriftCheckRunner.run(), a quarantine when the host callsDriftSweepCapable.sweep().Changed in this review round:
GovernanceOperationsServiceindiceis the single entry point — read (latest reports, global and per context, plus the declaration in force and the version the last completed sweep reconciled against), run (a check answering the full impact a sweep would evaluate,declaredDiffincluded), release (one call per proposition, context-checked before it writes).GovernanceControllerserves the five operations on/api/v1/metamodel;GovernanceToolsexposes the same five as@LlmTooltools; both call the one service. EXPERIMENTAL, marked@ApiStatus.Experimentalin code across the stack. The routes activate only when the host writes@Import(DiceRestConfiguration)and aDeclaredSchemaSourceis declared — the same activation as every other DICE controller, carried by a deferred import so the condition sees autoconfigured beans.GovernanceToolsis host-constructed likeDiscoveryTools; no auto-configuration registers a controller or a tool object. Per-report release is deliberately absent: nothing in the model ties a proposition to the report whose application held it, and the doc says what closing that needs.ObserveOnlyDriftCheckRunneris deleted andDriftModereduces toOFF | OBSERVE— the runner is report-only structurally, so the decorator had nothing left to downgrade.DiceEventListeneron the context; the derived-ownership schema wiring from feat(dice-storage): Drivine drift-report store and observed-schema source #87 is registered here; the HTTP gate re-checks the declared schema directly.Breaking changes: none. A host with no
DeclaredSchemaSourcebean sees no metamodel beans at all, proven by a context probe test.flowchart TD A{DeclaredSchemaSource bean?} -- no --> Z[no metamodel beans at all] A -- yes --> B{metamodel.enabled} B -- false --> Z B -- true --> C[stores, observed schema, differs, policy, sweep, runner] C --> F[GovernanceOperationsService; REST via host Import of DiceRestConfiguration; tools host-constructed] F --> G[read reports and declared version] F --> H[run a check on demand] F --> I[release one proposition from quarantine] J[host calls DriftSweepCapable.sweep] --> K[quarantine, deliberate and evented]Landing
DiceStorageAutoConfiguration.ktconflicts too and is resolved by hand from the union worktree's committed adaptation.ExtractionRunSchemajoins this stack'sDiceStorageSchemaderived-ownership contract (object declaration,overrideonspecs(), bookkeeping relationship types, catalog and test beans).DiceStorageSchemaRegistrationTestfails until it is applied — that is the guard working.undoSingleCollapsestays as a deprecated overload (Source-revision provenance: authoritative collector fold and undo #92). Downstream callers move toCollapseUndoCommandwhen convenient.