Rename Lossless/Lossy to Hyperview/View #6

Merged
lentil merged 4 commits from chore/rename-as-hyperview into main 2025-07-09 14:37:37 -05:00
23 changed files with 51 additions and 51 deletions
Showing only changes of commit 0978302110 - Show all commits

View File

@ -60,7 +60,7 @@ npm run example-app
- `src/node.ts`: Main `RhizomeNode` class orchestrating all components - `src/node.ts`: Main `RhizomeNode` class orchestrating all components
- `src/delta.ts`: Delta data structures and conversion logic - `src/delta.ts`: Delta data structures and conversion logic
- `src/hyperview.ts`: Core hyperview view implementation - `src/hyperview.ts`: Core hyperview implementation
- `src/collection-basic.ts`: Basic collection implementation - `src/collection-basic.ts`: Basic collection implementation
- `src/http/api.ts`: REST API endpoints - `src/http/api.ts`: REST API endpoints
- `src/pub-sub.ts`: Network communication layer - `src/pub-sub.ts`: Network communication layer

View File

@ -1,5 +1,5 @@
# Test structure # Test structure
- before test, initialize node and hyperview view - before test, initialize node and hyperview
- when test begins, create and ingest a series of deltas - when test begins, create and ingest a series of deltas
- instantiate a resolver, in this case using custom resolver plugins - instantiate a resolver, in this case using custom resolver plugins
- call the resolver's initializer with the view - call the resolver's initializer with the view

View File

@ -153,11 +153,11 @@ describe('Schema System', () => {
expect(schemaRegistry.hasCircularDependencies()).toBe(true); expect(schemaRegistry.hasCircularDependencies()).toBe(true);
}); });
test('should validate hyperview views against schemas', () => { test('should validate hyperviews against schemas', () => {
const userSchema = CommonSchemas.User(); const userSchema = CommonSchemas.User();
schemaRegistry.register(userSchema); schemaRegistry.register(userSchema);
// Create a valid hyperview view // Create a valid hyperview
const validView: HyperviewViewOne = { const validView: HyperviewViewOne = {
id: 'user123', id: 'user123',
propertyDeltas: { propertyDeltas: {
@ -371,7 +371,7 @@ describe('Schema System', () => {
expect(invalidEntities[0].entityId).toBe('user3'); expect(invalidEntities[0].entityId).toBe('user3');
}); });
test('should apply schema to hyperview views', async () => { test('should apply schema to hyperviews', async () => {
const userSchema = CommonSchemas.User(); const userSchema = CommonSchemas.User();
const collection = new TypedCollectionImpl<{ const collection = new TypedCollectionImpl<{
name: string; name: string;

View File

@ -1,6 +1,6 @@
/** /**
* Tests for hyperview view compose() and decompose() bidirectional conversion * Tests for hyperview compose() and decompose() bidirectional conversion
* Ensures that deltas can be composed into hyperview views and decomposed back * Ensures that deltas can be composed into hyperviews and decomposed back
* to the original deltas with all pointer relationships preserved. * to the original deltas with all pointer relationships preserved.
*/ */
@ -31,7 +31,7 @@ describe('Hyperview View Compose/Decompose', () => {
// Ingest the deltas // Ingest the deltas
nameDeltas.forEach(delta => node.hyperview.ingestDelta(delta)); nameDeltas.forEach(delta => node.hyperview.ingestDelta(delta));
// Compose hyperview view // Compose hyperview
const composed = node.hyperview.compose(['alice']); const composed = node.hyperview.compose(['alice']);
const aliceView = composed['alice']; const aliceView = composed['alice'];

View File

@ -180,7 +180,7 @@ describe('Negation System', () => {
}); });
describe('Hyperview View Integration', () => { describe('Hyperview View Integration', () => {
test('should filter negated deltas in hyperview views', () => { test('should filter negated deltas in hyperviews', () => {
// Create original delta // Create original delta
const originalDelta = createDelta('user1', 'host1') const originalDelta = createDelta('user1', 'host1')
.setProperty('user123', 'name', 'Alice') .setProperty('user123', 'name', 'Alice')

View File

@ -6,7 +6,7 @@ import {createDelta} from '@src/core/delta-builder';
describe('Hyperview', () => { describe('Hyperview', () => {
const node = new RhizomeNode(); const node = new RhizomeNode();
test('creates a hyperview view of keanu as neo in the matrix', () => { test('creates a hyperview of keanu as neo in the matrix', () => {
const delta = createDelta('a', 'h') const delta = createDelta('a', 'h')
.addPointer('actor', 'keanu', 'roles') .addPointer('actor', 'keanu', 'roles')
.addPointer('role', 'neo', 'actor') .addPointer('role', 'neo', 'actor')

View File

@ -39,7 +39,7 @@ class Summarizer extends Lossy<Summary> {
reducer(acc: Summary, cur: HyperviewViewOne): Summary { reducer(acc: Summary, cur: HyperviewViewOne): Summary {
this.debug(`Processing view for entity ${cur.id} (referenced as: ${cur.referencedAs?.join(', ')})`); this.debug(`Processing view for entity ${cur.id} (referenced as: ${cur.referencedAs?.join(', ')})`);
this.debug(`hyperview view:`, JSON.stringify(cur)); this.debug(`hyperview:`, JSON.stringify(cur));
if (cur.referencedAs?.includes("role")) { if (cur.referencedAs?.includes("role")) {
this.debug(`Found role entity: ${cur.id}`); this.debug(`Found role entity: ${cur.id}`);

View File

@ -61,7 +61,7 @@ describe('Nested Object Resolution', () => {
.buildV1(); .buildV1();
node.hyperview.ingestDelta(friendshipDelta); node.hyperview.ingestDelta(friendshipDelta);
// Get Alice's hyperview view // Get Alice's hyperview
const aliceViews = node.hyperview.compose(['alice']); const aliceViews = node.hyperview.compose(['alice']);
const aliceView = aliceViews['alice']; const aliceView = aliceViews['alice'];

View File

@ -103,7 +103,7 @@ classDiagram
- Represents atomic changes in the system - Represents atomic changes in the system
- Contains pointers to entities and their properties - Contains pointers to entities and their properties
3. **Hyperview**: Manages the hyperview view of data 3. **Hyperview**: Manages the hyperview of data
- Maintains the complete history of deltas - Maintains the complete history of deltas
- Provides methods to view and compose entity states - Provides methods to view and compose entity states

View File

@ -10,7 +10,7 @@ The `CustomResolver` class is the main entry point for the Custom Resolver syste
class CustomResolver { class CustomResolver {
/** /**
* Creates a new CustomResolver instance * Creates a new CustomResolver instance
* @param view The hyperview view to resolve * @param view The hyperview to resolve
* @param config Plugin configuration * @param config Plugin configuration
*/ */
constructor( constructor(
@ -48,7 +48,7 @@ class CustomResolver {
Creates a new instance of the CustomResolver. Creates a new instance of the CustomResolver.
**Parameters:** **Parameters:**
- `view: HyperviewView` - The hyperview view containing the data to resolve - `view: HyperviewView` - The hyperview containing the data to resolve
- `config: ResolverConfig` - Configuration object mapping property IDs to their resolver plugins - `config: ResolverConfig` - Configuration object mapping property IDs to their resolver plugins
**Example:** **Example:**
@ -148,7 +148,7 @@ The resolver may throw the following errors:
import { CustomResolver, LastWriteWinsPlugin } from './resolver'; import { CustomResolver, LastWriteWinsPlugin } from './resolver';
import { HyperviewView } from '../hyperview-view'; import { HyperviewView } from '../hyperview-view';
// Create a hyperview view with some data // Create a hyperview with some data
const view = new HyperviewView(); const view = new HyperviewView();
// ... add data to the view ... // ... add data to the view ...

View File

@ -26,7 +26,7 @@ import { CustomResolver } from '../src/views/resolvers/custom-resolvers';
import { LastWriteWinsPlugin } from '../src/views/resolvers/custom-resolvers/plugins'; import { LastWriteWinsPlugin } from '../src/views/resolvers/custom-resolvers/plugins';
import { Hyperview } from '../src/views/hyperview'; import { Hyperview } from '../src/views/hyperview';
// Create a hyperview view // Create a hyperview
const hyperview = new Hyperview(); const hyperview = new Hyperview();
// Create a resolver with a last-write-wins strategy // Create a resolver with a last-write-wins strategy
@ -34,7 +34,7 @@ const resolver = new CustomResolver(hyperview, {
myProperty: new LastWriteWinsPlugin() myProperty: new LastWriteWinsPlugin()
}); });
// Process updates through the hyperview view // Process updates through the hyperview
// hyperview.applyDelta(delta); // hyperview.applyDelta(delta);
// Get resolved values for specific entities // Get resolved values for specific entities

View File

@ -18,7 +18,7 @@ type User = {
(async () => { (async () => {
const rhizomeNode = new RhizomeNode(); const rhizomeNode = new RhizomeNode();
// Enable API to read hyperview view // Enable API to read hyperview
rhizomeNode.httpServer.httpApi.serveHyperview(); rhizomeNode.httpServer.httpApi.serveHyperview();
const users = new BasicCollection("user"); const users = new BasicCollection("user");

View File

@ -17,7 +17,7 @@ Phase 4 recognizes that in Rhizome, **deltas ARE relationships**. Instead of add
- **All tests passing**: 21/21 suites, 183/183 tests (100%) - **All tests passing**: 21/21 suites, 183/183 tests (100%)
- **Delta system**: Fully functional with pointers expressing relationships - **Delta system**: Fully functional with pointers expressing relationships
- **Negation system**: Can invalidate deltas (and thus relationships) - **Negation system**: Can invalidate deltas (and thus relationships)
- **Query system**: Basic traversal of hyperview views - **Query system**: Basic traversal of hyperviews
- **Schema system**: Can describe entity structures - **Schema system**: Can describe entity structures
- **Resolver system**: Application-level interpretation of deltas - **Resolver system**: Application-level interpretation of deltas

View File

@ -19,7 +19,7 @@ The rhizome-node implementation demonstrates strong alignment with core spec con
- **Tests**: Good coverage of basic transformation, filtering by creator/host - **Tests**: Good coverage of basic transformation, filtering by creator/host
3. **Lossy Views** 3. **Lossy Views**
- **Spec**: Compression of hyperview views using resolution strategies - **Spec**: Compression of hyperviews using resolution strategies
- **Implementation**: Initializer/reducer/resolver pattern provides flexibility - **Implementation**: Initializer/reducer/resolver pattern provides flexibility
- **Tests**: Domain-specific example (Role/Actor/Film) demonstrates concept - **Tests**: Domain-specific example (Role/Actor/Film) demonstrates concept

14
spec.md
View File

@ -8,11 +8,11 @@
* a `primitive` is a literal string, number or boolean value whose meaning is not tied up in its being a reference to a larger whole. * a `primitive` is a literal string, number or boolean value whose meaning is not tied up in its being a reference to a larger whole.
* An `object` is a composite object whose entire existence is encoded as the set of deltas that reference it. An object is identified by a unique `reference`, and every delta that includes that `reference` is asserting a claim about some property of that object. * An `object` is a composite object whose entire existence is encoded as the set of deltas that reference it. An object is identified by a unique `reference`, and every delta that includes that `reference` is asserting a claim about some property of that object.
* A `negation` is a specific kind of delta that includes a pointer with the name `negates`, a `target` reference to another delta, and a `context` called `negated_by`. * A `negation` is a specific kind of delta that includes a pointer with the name `negates`, a `target` reference to another delta, and a `context` called `negated_by`.
* a `schema` represents a template by which an `object` can be compiled into a `hyperview view`. A schema specifies which properties of that object are included, and it specifies schemas for the objects references by the deltas within those properties. A schema must terminate in primitive schemas to avoid an infinite regress. * a `schema` represents a template by which an `object` can be compiled into a `hyperview`. A schema specifies which properties of that object are included, and it specifies schemas for the objects references by the deltas within those properties. A schema must terminate in primitive schemas to avoid an infinite regress.
* For instance, a `hyperview view` "User" of a user may include references to friends. If those friends are in turn encoded as instances of the "User" schema then all of *their* friends would be fully encoded, etc. * For instance, a `hyperview` "User" of a user may include references to friends. If those friends are in turn encoded as instances of the "User" schema then all of *their* friends would be fully encoded, etc.
* This could lead to circular references and arbitrarily deep nesting, which runs into the problem of "returning the entire graph". So our schema should specify, for instance, that the "friends" field apply the "Summary" schema to referenced users rather than the "User" schema, where the "Summary" schema simply resolves to username and photo. * This could lead to circular references and arbitrarily deep nesting, which runs into the problem of "returning the entire graph". So our schema should specify, for instance, that the "friends" field apply the "Summary" schema to referenced users rather than the "User" schema, where the "Summary" schema simply resolves to username and photo.
* A `hyperview view` is a representation of an `object` that includes a full inventory of all of the deltas that compose that object. So for instance, a hyperview view of the object representing the user "Alice" might include `alice.name`, which contains an array of all deltas with a pointer whose `target` is the ID of Alice and whose context is `name`. Such deltas would likely include a second pointer with the name `name` and the target a primitive string "Alice", for instance. * A `hyperview` is a representation of an `object` that includes a full inventory of all of the deltas that compose that object. So for instance, a hyperview of the object representing the user "Alice" might include `alice.name`, which contains an array of all deltas with a pointer whose `target` is the ID of Alice and whose context is `name`. Such deltas would likely include a second pointer with the name `name` and the target a primitive string "Alice", for instance.
* A `hyperview view` may also include nested delta/object layering. Consider `alice.friends`, which would include all deltas asserting friendship between Alice and some other person. Each such delta would reference a different friend object. In a hyperview view, these references would be expanded to contain hyperview views of those friends. Schemas, as defined above, would be applied to constrain tree depth and avoid infinite regress. * A `hyperview` may also include nested delta/object layering. Consider `alice.friends`, which would include all deltas asserting friendship between Alice and some other person. Each such delta would reference a different friend object. In a hyperview, these references would be expanded to contain hyperviews of those friends. Schemas, as defined above, would be applied to constrain tree depth and avoid infinite regress.
* A `view view` is a compression of a `hyperview view` that removes delta information and flattens the structure into a standard domain object, typically in JSON. So instead of `alice.name` resolving to a list of deltas that assert the object's name it might simply resolve to `"alice"`. * A `view view` is a compression of a `hyperview` that removes delta information and flattens the structure into a standard domain object, typically in JSON. So instead of `alice.name` resolving to a list of deltas that assert the object's name it might simply resolve to `"alice"`.
* Note that in a hyperview view any property of an object necessarily resolves to a set of deltas, even if it's an empty set, because we cannot anticipate how many deltas exist that assert values on that context. * Note that in a hyperview any property of an object necessarily resolves to a set of deltas, even if it's an empty set, because we cannot anticipate how many deltas exist that assert values on that context.
* In collapsing a hyperview view into a view view we may specify `resolution strategies` on each field of the schema. A resolution strategy takes as input the set of all deltas targeting that context and returns as output the value in the view view. So if we have 15 deltas asserting the value for an object's name, our resolution strategy may simply say "return the target of the `name` pointer associated with the most recent delta", or it may say "return an array of names". If the value is numeric it may say "take the max" or "take the min" or "take the average". * In collapsing a hyperview into a view view we may specify `resolution strategies` on each field of the schema. A resolution strategy takes as input the set of all deltas targeting that context and returns as output the value in the view view. So if we have 15 deltas asserting the value for an object's name, our resolution strategy may simply say "return the target of the `name` pointer associated with the most recent delta", or it may say "return an array of names". If the value is numeric it may say "take the max" or "take the min" or "take the average".

View File

@ -71,7 +71,7 @@ export class TypedCollectionImpl<T extends Record<string, unknown>>
// Validate an entity against the schema // Validate an entity against the schema
validate(entity: T): SchemaValidationResult { validate(entity: T): SchemaValidationResult {
// Convert entity to a mock hyperview view for validation // Convert entity to a mock hyperview for validation
const mockHyperviewView: HyperviewViewOne = { const mockHyperviewView: HyperviewViewOne = {
id: 'validation-mock', id: 'validation-mock',
referencedAs: [], referencedAs: [],
@ -88,7 +88,7 @@ export class TypedCollectionImpl<T extends Record<string, unknown>>
return this.schemaRegistry.validate('validation-mock', this.schema.id, mockHyperviewView); return this.schemaRegistry.validate('validation-mock', this.schema.id, mockHyperviewView);
} }
// Apply schema to a hyperview view // Apply schema to a hyperview
apply(view: HyperviewViewOne): SchemaAppliedView { apply(view: HyperviewViewOne): SchemaAppliedView {
return this.schemaRegistry.applySchema(view, this.schema.id, this.applicationOptions); return this.schemaRegistry.applySchema(view, this.schema.id, this.applicationOptions);
} }
@ -202,7 +202,7 @@ export class TypedCollectionImpl<T extends Record<string, unknown>>
} }
const hyperviewView = this.rhizomeNode.hyperview.compose(this.getIds()); const hyperviewView = this.rhizomeNode.hyperview.compose(this.getIds());
if (!hyperviewView) { if (!hyperviewView) {
debug(`No hyperview view found`) debug(`No hyperview found`)
return []; return [];
} }
debug(`getValidEntities, hyperviewView: ${JSON.stringify(hyperviewView, null, 2)}`) debug(`getValidEntities, hyperviewView: ${JSON.stringify(hyperviewView, null, 2)}`)

View File

@ -148,7 +148,7 @@ export class HttpApi {
}); });
}); });
// Get a hyperview view of a single domain entity // Get a hyperview of a single domain entity
this.router.get('/hyperview/:id', (req: express.Request, res: express.Response) => { this.router.get('/hyperview/:id', (req: express.Request, res: express.Response) => {
const {params: {id}} = req; const {params: {id}} = req;
const v = this.rhizomeNode.hyperview.compose([id]); const v = this.rhizomeNode.hyperview.compose([id]);

View File

@ -91,9 +91,9 @@ export class RhizomeNode {
}: { syncOnStart?: boolean } = {}): Promise<void> { }: { syncOnStart?: boolean } = {}): Promise<void> {
debug(`[${this.config.peerId}]`, 'Starting node (waiting for ready)...'); debug(`[${this.config.peerId}]`, 'Starting node (waiting for ready)...');
// Connect our hyperview view to the delta stream // Connect our hyperview to the delta stream
this.deltaStream.subscribeDeltas(async (delta) => { this.deltaStream.subscribeDeltas(async (delta) => {
// Ingest into hyperview view // Ingest into hyperview
this.hyperview.ingestDelta(delta); this.hyperview.ingestDelta(delta);
// Also store in persistent storage // Also store in persistent storage
@ -150,11 +150,11 @@ export class RhizomeNode {
} }
/** /**
* Sync existing hyperview view data to persistent storage * Sync existing hyperview data to persistent storage
* Useful for migrating from memory-only to persistent storage * Useful for migrating from memory-only to persistent storage
*/ */
async syncToStorage(): Promise<void> { async syncToStorage(): Promise<void> {
debug(`[${this.config.peerId}]`, 'Syncing hyperview view to storage'); debug(`[${this.config.peerId}]`, 'Syncing hyperview to storage');
const allDeltas = this.deltaStream.deltasAccepted; const allDeltas = this.deltaStream.deltasAccepted;
let synced = 0; let synced = 0;

View File

@ -96,9 +96,9 @@ export class QueryEngine {
const candidateEntityIds = this.discoverEntitiesBySchema(schemaId); const candidateEntityIds = this.discoverEntitiesBySchema(schemaId);
debug(`Found ${candidateEntityIds.length} candidate entities for schema ${schemaId}`); debug(`Found ${candidateEntityIds.length} candidate entities for schema ${schemaId}`);
// 2. Compose hyperview views for all candidates // 2. Compose hyperviews for all candidates
const allViews = this.hyperview.compose(candidateEntityIds, options.deltaFilter); const allViews = this.hyperview.compose(candidateEntityIds, options.deltaFilter);
debug(`Composed ${Object.keys(allViews).length} hyperview views`); debug(`Composed ${Object.keys(allViews).length} hyperviews`);
// 3. Apply JSON Logic filter if provided // 3. Apply JSON Logic filter if provided
let filteredViews: HyperviewViewMany = allViews; let filteredViews: HyperviewViewMany = allViews;
@ -195,8 +195,8 @@ export class QueryEngine {
} }
/** /**
* Apply JSON Logic filter to hyperview views * Apply JSON Logic filter to hyperviews
* This requires converting each hyperview view to a queryable object * This requires converting each hyperview to a queryable object
*/ */
private applyJsonLogicFilter( private applyJsonLogicFilter(
views: HyperviewViewMany, views: HyperviewViewMany,
@ -215,7 +215,7 @@ export class QueryEngine {
for (const [entityId, view] of Object.entries(views)) { for (const [entityId, view] of Object.entries(views)) {
try { try {
// Convert hyperview view to queryable object using schema // Convert hyperview to queryable object using schema
const queryableObject = this.hyperviewViewToQueryableObject(view, schema); const queryableObject = this.hyperviewViewToQueryableObject(view, schema);
// Apply JSON Logic filter // Apply JSON Logic filter
@ -246,7 +246,7 @@ export class QueryEngine {
} }
/** /**
* Convert a hyperview view to a queryable object based on schema * Convert a hyperview to a queryable object based on schema
* Uses simple resolution strategies for now * Uses simple resolution strategies for now
*/ */
private hyperviewViewToQueryableObject(view: HyperviewViewOne, schema: ObjectSchema): Record<string, unknown> { private hyperviewViewToQueryableObject(view: HyperviewViewOne, schema: ObjectSchema): Record<string, unknown> {
@ -255,7 +255,7 @@ export class QueryEngine {
_referencedAs: view.referencedAs _referencedAs: view.referencedAs
}; };
// Convert each schema property from hyperview view deltas // Convert each schema property from hyperview deltas
for (const [propertyId, propertySchema] of Object.entries(schema.properties)) { for (const [propertyId, propertySchema] of Object.entries(schema.properties)) {
const deltas = view.propertyDeltas[propertyId] || []; const deltas = view.propertyDeltas[propertyId] || [];

View File

@ -480,7 +480,7 @@ export class DefaultSchemaRegistry implements SchemaRegistry {
const referenceIds = this.extractReferenceIdsFromDelta(delta, parentEntityId); const referenceIds = this.extractReferenceIdsFromDelta(delta, parentEntityId);
for (const referenceId of referenceIds) { for (const referenceId of referenceIds) {
try { try {
// Get the referenced entity's hyperview view // Get the referenced entity's hyperview
const referencedViews = hyperviewView.compose([referenceId]); const referencedViews = hyperviewView.compose([referenceId]);
const referencedView = referencedViews[referenceId]; const referencedView = referencedViews[referenceId];

View File

@ -76,7 +76,7 @@ export interface SchemaApplicationOptions {
strictValidation?: boolean; strictValidation?: boolean;
} }
// Applied schema result - a hyperview view filtered through a schema // Applied schema result - a hyperview filtered through a schema
export interface SchemaAppliedView { export interface SchemaAppliedView {
id: DomainEntityID; id: DomainEntityID;
schemaId: SchemaID; schemaId: SchemaID;

View File

@ -1,5 +1,5 @@
// We have the hyperview transformation of the delta stream. // We have the hyperview transformation of the delta stream.
// We want to enable transformations from the hyperview view, // We want to enable transformations from the hyperview,
// into various possible "view" views that combine or exclude some information. // into various possible "view" views that combine or exclude some information.
import Debug from 'debug'; import Debug from 'debug';
@ -49,7 +49,7 @@ export abstract class Lossy<Accumulator, Result = Accumulator> {
const hyperviewPartial = this.hyperview.compose([entityId], combinedFilter); const hyperviewPartial = this.hyperview.compose([entityId], combinedFilter);
if (!hyperviewPartial) { if (!hyperviewPartial) {
// This should not happen; this should only be called after the hyperview view has been updated // This should not happen; this should only be called after the hyperview has been updated
console.error(`Hyperview view for entity ${entityId} not found`); console.error(`Hyperview view for entity ${entityId} not found`);
return; return;
} }

View File

@ -12,7 +12,7 @@ This document tracks work needed to achieve full specification compliance, organ
- [x] Add validation for pointer consistency - [x] Add validation for pointer consistency
### 1.2 Complete Transaction Support ✅ (mostly) ### 1.2 Complete Transaction Support ✅ (mostly)
- [x] Implement transaction-based filtering in hyperview views - [x] Implement transaction-based filtering in hyperviews
- [x] Add transaction grouping in delta streams - [x] Add transaction grouping in delta streams
- [x] Test atomic transaction operations - [x] Test atomic transaction operations
- [ ] Add transaction rollback capabilities (deferred - not critical for spec parity) - [ ] Add transaction rollback capabilities (deferred - not critical for spec parity)
@ -29,7 +29,7 @@ This document tracks work needed to achieve full specification compliance, organ
### 2.1 Negation Deltas ✅ ### 2.1 Negation Deltas ✅
- [x] Implement negation delta type with "negates" pointer - [x] Implement negation delta type with "negates" pointer
- [x] Add "negated_by" context handling - [x] Add "negated_by" context handling
- [x] Update hyperview view to handle negations - [x] Update hyperview to handle negations
- [x] Update view resolvers to respect negations - [x] Update view resolvers to respect negations
- [x] Add comprehensive negation tests - [x] Add comprehensive negation tests
@ -50,7 +50,7 @@ This document tracks work needed to achieve full specification compliance, organ
### 3.1 Query Engine Foundation ✅ ### 3.1 Query Engine Foundation ✅
- [x] Implement JSON Logic parser (using json-logic-js) - [x] Implement JSON Logic parser (using json-logic-js)
- [x] Create query planner for hyperview views - [x] Create query planner for hyperviews
- [x] Add query execution engine (QueryEngine class) - [x] Add query execution engine (QueryEngine class)
- [x] Implement schema-driven entity discovery - [x] Implement schema-driven entity discovery
- [x] Enable the skipped query tests - [x] Enable the skipped query tests
@ -91,7 +91,7 @@ This document tracks work needed to achieve full specification compliance, organ
### 4.4 Schema-as-Deltas (Meta-Schema System) ### 4.4 Schema-as-Deltas (Meta-Schema System)
- [ ] Define schema entities that are stored as deltas in the system - [ ] Define schema entities that are stored as deltas in the system
- [ ] Implement schema queries that return schema instances from hyperview views - [ ] Implement schema queries that return schema instances from hyperviews
- [ ] Create schema evolution through delta mutations - [ ] Create schema evolution through delta mutations
- [ ] Add temporal schema queries (schema time-travel) - [ ] Add temporal schema queries (schema time-travel)
- [ ] Build schema conflict resolution for competing schema definitions - [ ] Build schema conflict resolution for competing schema definitions