feat: layered database structure and AI guidance skills#150
Open
krisnye wants to merge 28 commits into
Open
Conversation
Move samples toward namespaced database layers and expand data-ai skills so agents can follow the same structure. Co-authored-by: Cursor <cursoragent@cursor.com>
…ture # Conflicts: # packages/data-lit-todo/package.json # packages/data-p2p-tictactoe/src/state/negotiation-plugin.ts
…tore Restructure both samples into the four-layer feature model and fix the supporting core types at the source. Core @adobe/data - Remove the separate transaction-context type. `Store` now carries `userId` and its index handles (`IX`); `ToStore<P>` includes indexes + partition keys. Transaction functions operate on `Store` directly — a store *is* the transaction context. Deletes `TransactionContext` / `ToTransactionContext`. - Fix `UIService.FromService` misclassifying a plain async fire-and-forget action (`() => Promise<void>`) as a transaction overload and wrongly requiring an argument; a genuine transaction has a synchronous commit signature (never a Promise), which is the correct discriminator. Samples (tic-tac-toe, todo) - `data/` is the specification: one immutable `State` with pure, unit-tested transforms/derivations. `ecs/` is the materialised view; computeds and transactions are verified against the `data/` precedent by conformance tests. Add `services/` (async ports) and `ui/`. - Facet-named database layers, no feature/app names in the ladder: Core -> Index -> Transaction -> Computed -> Service -> Action. - todo: async name-generator service, todo-analytics service, and an `actions/` layer where the UI dispatches actions that record analytics and call one transaction (async action brackets the slow call for timing). Rules & tooling - Path-mapped `structure/` rules mirroring the feature folders (adds data/state, ecs/actions); README + skill bundle updated. - Require Node >=22 (engines + .nvmrc) so live-reactivity paths are testable. Full-monorepo typecheck clean; test suite green on Node 22. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ests
Builds on the layered feature architecture with lazily-loaded features, a
many-to-many index demo, and a presentation-testing utility — plus fixes to
analytics, computed sharing, and flaky tests.
Multi-feature app (data-lit-todo)
- Restructure the sample into src/features/{main,assign}/. `main` imports each
peer feature's *schema* plugin (Database.Plugin `imports`, not `extends`) so
the shared store knows every schema without type-coupling or bundling the
feature's behavior.
- Feature elements lazily extend the live database on first connect
(DatabaseElement), so a feature's indexes/transactions/UI load only when used.
- New `assign` feature: a User archetype, a unique `usersByName` index and a
multi-value `todosByAssignee` index — the todo<->user many-to-many navigable
both ways; assignee dropdown + Users tab load lazily.
Services / actions
- todo-analytics is now named, strongly-typed methods (event vocabulary and
formatting owned by the service), with a stateless opaque timing token from
randomTodoRequested handed back to randomTodoAdded; named-object args.
Core @adobe/data
- Wrap db.derive computeds in Observe.withCache so N subscribers share one
computation (red/green test).
- Convert flaky wall-clock perf assertions to non-fatal warnings; the suite is
now deterministic and exits 0.
Presentation testing (@adobe/data-lit)
- Add Template — a DOM-free query over a Lit TemplateResult
(text/values/children/has/find) for asserting what a pure render(props)
declares. Pure and tree-shakeable.
- Make todo-row-presentation pure (move the drag hook into the element).
- Unit-test every Lit presentation in the repo (tictactoe, todo, p2p) via
Template; jsdom only where module-load side effects require it.
Rules updated for multi-feature composition, indexes/m2m, and the presentation
testing pattern. Full-monorepo typecheck clean; test suite green on Node 22.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Each vec/quat/mat4x4/line/plane function now lives in its own file with only the imports it uses, collected by the folder's public.ts barrel. Remove the <type>-functions.ts exemption from namespace.md; multi-export is now allowed only by explicit per-file/per-file-type approval. Delete the dead, unreferenced quat/constants/functions.ts duplicate. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rename each feature's core-database to persistent-database (the durable, serializable data model) and add a session-database layer that extends it, holding transient session state and the archetypes (a packing convenience, not persisted). Session components/resources declare nonPersistent: true explicitly. Add assertPersistencePartition to @adobe/data/ecs and a feature-root persistence-partition test per feature to verify the split. Fix a latent add-user guard that treated user entity id 0 as "not found". Also bundles the prior branch's uncommitted sample import-path corrections and layer-isolation rule-doc edits so the branch builds green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ared Add a nonShared schema flag and built-in component to @adobe/data (declared consistently with nonPersistent; no database behavior wired — smart-id work deferred). Restructure each feature's ECS schema into scope layers by the two orthogonal axes (shared/local × durable/ephemeral): document-database (shared+durable), optional settings-database (local+durable, nonShared), optional session-database (local+ephemeral, both flags); archetypes move to their own archetype-database layer above the scopes. Rename core→document; displayCompleted becomes a durable-local setting; dragPosition gains nonShared. Generalize the feature-root check to assertSchemaScopes and update the rules. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add Database.scope — document/settings/presence/session map transforms that stamp each scope's flag pair (document is identity), applied once where a layer is composed (e.g. components: Database.scope.session(components)) rather than per component/resource file. Component/resource files become scope-agnostic data re-exports; the layer states the scope. Unit-test the transforms; the feature-root assertSchemaScopes test verifies each layer applied the right one. Archetype layer composes across scopes unchanged. Update rules accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…scalCase A Schema is a runtime type, so a higher-order schema function that returns a new type-representing schema is a type constructor (like Readonly<T>) and takes PascalCase — matching Tuple and the *ResultSchema factories (5 of 6 already did). Revert the lone outlier nullable -> Nullable and codify the rule in namespace.md: PascalCase iff calling it yields a new runtime type; camelCase for annotators (withValidation), spec builders (from*), resolvers/transformers, and namespace methods. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ope helpers Replace the per-scope database layers (document/settings/session/archetype) with a single core-database/ per feature — four single-export files (core-database.ts + components.ts / resources.ts / archetypes.ts). Add Database.components / Database.resources / Database.archetypes: components and resources group declarations by schema scope (document/settings/presence/ session, all optional, documented for intellisense) and stamp the flags; resources enforce a default at the call; archetypes validate keys against the component map and preserve literal tuples. document passes schemas through by identity so cross-feature shared columns dedupe. Remove Database.scope and assertSchemaScopes. Promote shared name/assignees to data/. Collapse all transactions to CoreDatabase.Store; index-database extends core. Rewrite the ecs rules to match. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wrap Database.components / Database.resources (and stampScopes) return types in Simplify<…> so the merged scope groups render as one flat object type instead of an A & B & C & D intersection in hover/intellisense. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rules: fix example bugs (actions.md service-database import path; services.md db type TictactoeDatabase -> ComputedDatabase; computed.md facet wording) and tighten the features/ overview. Paths verified against the samples. Skills: make `structure` a thin bottom-up orchestrator that defers to the path-injected features/ rules (no restated layer detail); replace its README with a pointer and drop its stale references/ example tree. Delete the stale per-facet build skills (components, resources, archetypes, types, services, namespace, archetype-to-type) — they described the pre-ecs layout and only pointed at rules that now auto-load by path. Re-sync the installed .agents bundle (10 skills). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… root The cross-cutting rules the features/ bundle references (namespace, data-modelling, type-casts, cohesion, archetypes, plugin-modelling, element, lazy-element, presentation) now live in packages/data-ai/.claude/rules/ so the distributed bundle is self-contained; the repo symlinks them into root .claude/rules/ (as it already does features/). Add .claude to the package files[] so the rules ship, and note them in the bundle README. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bring back the per-phase feature-building skills as a flat set (Claude Code only discovers skills one level deep / flat in a plugin; nesting would only work in Cursor). One build-* skill per feature layer — build-data, build-services, build-core-database, build-indexes, build-transactions, build-computed, build-service-database, build-actions, build-ui — each thin: it scaffolds the layer and defers the how to the path-injected features/ rule. `structure` becomes the orchestrator that sequences them bottom-up. Re-sync the .agents bundle (19 skills). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
structure now describes only the feature's layer shape and dependency direction (the "what"); the build-* skills own the build order (the "how"), each stating its own place in the sequence. Re-sync .agents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
structure only restated the feature layering, which features/index.md (the overview rule) already covers as a superset. The "what" now lives solely in the features/ rules; the "how" in the build-* skills. Re-sync .agents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
structure is back as a minimal invokable entry that points to the features/ rules (the "what") without restating the overview. Re-sync .agents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the restated layering/examples — they live in features/index.md. structure is now just a one-line signpost to the features/ rules. Re-sync .agents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… / game) Add build-feature (composes the per-layer build-* skills bottom-up), build-application (composes build-feature for a base + lazy peer features, plus the imports/lazy-element wiring), and build-game (specializes build-application with the game-concept mapping). Higher-order skills reference the lower build-* concisely rather than restating them. Re-sync .agents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Give each per-layer build-* skill input/output: feature so they chain, and express the higher-order skills as pipelines of them: build-feature = /build-data |> … |> /build-ui (run via /x-execute, validated by /x-validate). build-application and build-game compose /build-feature. Re-sync .agents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The peer-import / lazy-load / entry-point wiring is now its own build-app-entry skill, so build-application is a clean pipe: /build-feature |> /build-feature |> /build-app-entry. Re-sync .agents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add `review` (read-only assessment of built output against the features rules, tagging each issue code|skill|rule) and `meta-build`: given an app/game prompt and a target build command, it runs each phase in its own clean /x-subagent, reviews the output, and on issues edits the phase skill or a referenced rule (concise + general, never app-specific), re-running the phase up to N times (default 4) before moving on. Ends with a read-only whole-product review that changes nothing and summarizes per-phase iterations and which skills/rules were edited. Re-sync .agents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ystemDatabase
@adobe/data:
- add equalsUnordered (deep equality ignoring array + object ordering)
- add Database.toSystemDatabase — cast-free writable-store lens (restrict's twin)
Conformance pattern (Store.create + raw transactions projection, cast-free):
- lit-asteroids, data-lit-todo, data-lit-tictactoe conformance suites
- per-transaction tests vs spec, shared data/state cases, ecs/conformance projection
Samples (meta-build): new lit-calculator and lit-asteroids packages.
data-lit: DatabaseElement.database accessor + pre-upgrade property fix (enforce
the UI restriction; expose the store to imperative-rendering subclasses).
AI guidance: build-systems skill + features/ecs/{systems,conformance} rules,
computed-key indexes, tag components, struct schemas, and related refinements.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…orm calculator - rename packages to match the data-lit-* convention (git mv, history preserved) - apply the spec↔impl conformance test pattern to data-lit-calculator (resource-only projection; per-transaction expectConforms tests) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…a-ai bundle notice FeatureDatabase standard: - alias the assembled feature database once (ecs/feature-database.ts) so consumers never name the varying topmost layer; cross-feature imports use <Feature>CoreDatabase / <Feature>Database. Applied across the four samples; rewired data-p2p-tictactoe. Guidance in features/ecs/index.md + element.md (incl. the extend-friendly element exception). Asteroids collision: - resolveBulletHits defers split children (no same-frame chain-annihilation) - swept segment-vs-circle bullet detection (Collision.segmentCircleOverlap) so fast bullets can't tunnel through asteroids; ecs system + transaction match. data-ai: write a do-not-edit CLAUDE.md into the installed bundle; bump script now syncs plugin.json version (and corrected the existing drift). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ame tick-loop - createStore builds from the schema-complete layer's plugin directly (Store.create(IndexDatabase.plugin) / CoreDatabase.plugin), not FeatureDatabase. - new rule function-references.md: pass functions by reference, never wrap in an identity arrow (only the rare unbound-method case wraps). Swept the transaction conformance tests to bare spec/apply references, leaving genuine adapters. - rename system-database/conformance.test.ts -> tick-loop.test.ts (it verifies the whole tick equals State.step); guidance reference updated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The calculator (resource-only, no entities/systems) added little over todo — dropping it; asteroids, todo, and tictactoe cover the pattern. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Formalizes a feature-oriented architecture for
@adobe/dataapps, encodes it as path-injected AI rules, and ships composable build skills that generate it — with four worked samples.The feature structure
Each feature is a
features/<name>/folder in four layers (higher imports lower):data/— the pure spec: the whole feature as one immutableStatewith pure, fully-tested transforms. The source of truth; performance irrelevant.services/— async capability contracts (optional).ecs/— the efficient implementation: a layeredDatabase.Pluginstack (core → index → transaction → computed → service → action → system), each layer its own namespace; the assembled top aliased once asFeatureDatabaseso consumers never name the varying topmost layer.ui/— presentation (lazy wrapper / container / pure render / css).data/(spec) andecs/(impl) are tied by conformance: a test-onlyState↔store projection proves each transaction/system equal to the pure transform it stands for, so the ecs layer can be largely mechanical and agent-generated. Apps compose features — one base host + lazily-loaded peers whose schema the baseimportswithout type/bundle coupling.Matching AI rules —
packages/data-ai/.claude/rules/Distributable
.mdrules whosepaths:globs mirror the folder tree one-to-one: editingecs/transactions/foo.tsinjects exactly that layer's rule plus the cross-cutting ones (namespace, data-modelling, type-casts, conformance, …). Guidance lives at the same path shape as the code it governs, present at authoring time.Build skills —
packages/data-ai/skills/Composable
build-*leaf skills (build-data,build-core-database,build-transactions,build-computed,build-systems,build-ui, …) piped bottom-up bybuild-feature, and bybuild-application/build-game.meta-builddrives the loop and polishes the rules/skills against a concrete app prompt.Samples + core support
Worked samples:
data-lit-asteroids(real-time ECS — systems, spatial broad-phase, swept collision), anddata-lit-todo/data-lit-tictactoeconformed to the pattern. Supporting@adobe/data:equalsUnordered,Database.toSystemDatabase(writable-store lens),DatabaseElementaccessor/restriction fixes.Test plan
pnpm typecheck+pnpm lintgreendata-aiskills install/resolve