From 0630f8b1e844de794b16f5bd140f2f199878760b Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 26 Oct 2026 17:34:39 +0000 Subject: [PATCH] docs: delete eight obsolete planning docs and point the root docs at the live pages Ruling A on the obsolete-docs decision card. Deleted, history kept in git: docs/NEXT_STEP.md, docs/DX_ROADMAP.md, docs/PLUGIN_ECOSYSTEM_MAP.md, docs/upgrading-to-11.md, docs/v17-docs-sweep.md, docs/launch-readiness.md, docs/plans/m1-project-artifact-schema.md and docs/plans/release-15.1-test-plan.md. - ARCHITECTURE.md becomes a pointer to the published architecture page. - Root CHANGELOG.md keeps its history and gains a top line pointing at content/docs/releases/; its three links to the 11.x upgrade guide now resolve at commit df8aac41. - RELEASE_NOTES.md is marked frozen, loses the "(in progress)" marker and the reference to a changeset file that never existed. - docs/audits/README.md states the open -> closed -> archive/ lifecycle. - Inbound references are rewritten: the published client-sdk page, the platform-checklist README, packages/metadata/ROADMAP.md and PLATFORM_GAPS_FROM_TEMPLATES.md; source comments that cited a deleted file now name the commit that holds it. - check-required-contexts drops docs/launch-readiness.md from its scan set (it hard-fails on a surface it cannot read); check-doc-authoring's example guide name is updated. Claude-Session: https://claude.ai/code/session_01SQ8bET7S4BDrvJdXyuLdYi Co-authored-by: Claude --- ARCHITECTURE.md | 725 +----------------- CHANGELOG.md | 9 +- RELEASE_NOTES.md | 6 +- content/docs/api/client-sdk.mdx | 2 +- docs/DX_ROADMAP.md | 232 ------ docs/NEXT_STEP.md | 239 ------ docs/PLATFORM_GAPS_FROM_TEMPLATES.md | 2 +- docs/PLUGIN_ECOSYSTEM_MAP.md | 242 ------ docs/audits/README.md | 2 + docs/launch-readiness.md | 268 ------- docs/plans/m1-project-artifact-schema.md | 136 ---- docs/plans/release-15.1-test-plan.md | 112 --- docs/qa/platform-checklist/README.md | 4 +- docs/upgrading-to-11.md | 154 ---- docs/v17-docs-sweep.md | 193 ----- packages/metadata/ROADMAP.md | 1 - .../services/service-automation/src/engine.ts | 3 +- .../services/service-automation/src/plugin.ts | 3 +- .../src/in-memory-realtime-adapter.ts | 3 +- .../src/realtime-service-plugin.ts | 3 +- packages/spec/scripts/build-docs.ts | 1 - scripts/check-doc-authoring.mjs | 6 +- scripts/check-platform-checklist.mjs | 3 +- scripts/check-required-contexts.mjs | 3 +- 24 files changed, 35 insertions(+), 2317 deletions(-) delete mode 100644 docs/DX_ROADMAP.md delete mode 100644 docs/NEXT_STEP.md delete mode 100644 docs/PLUGIN_ECOSYSTEM_MAP.md delete mode 100644 docs/launch-readiness.md delete mode 100644 docs/plans/m1-project-artifact-schema.md delete mode 100644 docs/plans/release-15.1-test-plan.md delete mode 100644 docs/upgrading-to-11.md delete mode 100644 docs/v17-docs-sweep.md diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index f9438f0e762..b7ad11207e7 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -1,721 +1,8 @@ # ObjectStack Architecture -> **v5.0 (2026): `project` → `environment`.** The runtime concept formerly called *Project* (per-tenant business workspace; Org/Project/Branch hierarchy) is now called *Environment* throughout the codebase: CLI flags (`--environment`/`-e`), HTTP paths (`/api/v1/environments/:environmentId/...`), headers (`X-Environment-Id`), env vars (`OS_ENVIRONMENT_ID`), exported symbols (`createSystemEnvironmentPlugin`, `SYSTEM_ENVIRONMENT_ID`), DB columns (`environment_id`), and JSON schemas (`EnvironmentArtifact`) all use the new term with no aliases or deprecation shims. The word "project" elsewhere in this document still refers to the npm/monorepo sense (i.e., the framework as a software project). See `.changeset/v5-project-to-environment-rename.md` for the full breaking-change list and ADR-0006 for the rationale. - - -> **Architecture Document** - Updated January 2026 -> -> This document provides a comprehensive overview of ObjectStack's microkernel architecture, package distribution, and design principles. - -## Table of Contents - -1. [Architecture Overview](#architecture-overview) -2. [Microkernel Design](#microkernel-design) -3. [Package Structure](#package-structure) -4. [Layer Architecture](#layer-architecture) -5. [Plugin System](#plugin-system) -6. [Dependency Graph](#dependency-graph) -7. [Design Decisions](#design-decisions) -8. [Additional Resources](#additional-resources) - ---- - -## Architecture Overview - -ObjectStack is built on a **microkernel architecture** inspired by operating system design principles. The system separates core functionality (the kernel) from business logic (plugins), enabling: - -- **Modularity**: Each component is independently developed, tested, and deployed -- **Extensibility**: New features added through plugins without modifying core -- **Testability**: Components can be mocked and tested in isolation -- **Technology Independence**: Swap implementations without breaking contracts - -### Core Principles - -1. **Protocol-First Design**: All interactions defined through Zod schemas -2. **Separation of Concerns**: Three distinct layers (QL, OS, UI) -3. **Dependency Injection**: Services registered and consumed through DI container -4. **Event-Driven Communication**: Plugins communicate via hooks/events -5. **Reverse Domain Naming**: Global uniqueness through domain notation - ---- - -## Microkernel Design - -### The ObjectKernel - -**Location**: `packages/core/src/kernel.ts` - -The ObjectKernel is the heart of the system, providing: - -``` -┌─────────────────────────────────────────────────────┐ -│ ObjectKernel (Core) │ -│ ┌───────────────────────────────────────────────┐ │ -│ │ Plugin Lifecycle Manager │ │ -│ │ • Dependency Resolution (Topological Sort) │ │ -│ │ • Init → Start → Destroy Phases │ │ -│ └───────────────────────────────────────────────┘ │ -│ ┌───────────────────────────────────────────────┐ │ -│ │ Service Registry (DI Container) │ │ -│ │ • registerService(name, service) │ │ -│ │ • getService(name): T │ │ -│ └───────────────────────────────────────────────┘ │ -│ ┌───────────────────────────────────────────────┐ │ -│ │ Event Bus (Hook System) │ │ -│ │ • hook(name, handler) │ │ -│ │ • trigger(name, ...args) │ │ -│ └───────────────────────────────────────────────┘ │ -│ ┌───────────────────────────────────────────────┐ │ -│ │ Logger (Pino-based) │ │ -│ │ • Server: JSON logs to stdout │ │ -│ │ • Browser: Console with pretty formatting │ │ -│ └───────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────┘ - │ - ┌─────────┴─────────┬──────────┬──────────┐ - │ │ │ │ -┌───▼────┐ ┌───────▼──┐ ┌──▼───┐ ┌───▼────┐ -│ObjectQL│ │ Driver │ │ Hono │ │ App │ -│ Plugin │ │ Plugin │ │Server│ │ Plugin │ -└────────┘ └──────────┘ └──────┘ └────────┘ -``` - -### Plugin Lifecycle - -``` -State Machine: -┌────────┐ -│ idle │ ← Initial state -└───┬────┘ - │ kernel.use(plugin) - ▼ -┌────────┐ -│ init │ ← Register services, subscribe to hooks -└───┬────┘ - │ kernel.bootstrap() - ▼ -┌────────┐ -│ start │ ← Connect to databases, start servers -└───┬────┘ - │ - ▼ -┌─────────┐ -│ running │ -└───┬─────┘ - │ kernel.shutdown() - ▼ -┌─────────┐ -│ destroy │ ← Clean up resources -└─────────┘ -``` - ---- - -## Package Structure - -ObjectStack is organized as a **monorepo** with distinct package layers: - -### Core Packages - -#### `@objectstack/spec` -**Location**: `packages/spec/` -**Role**: Protocol Definitions (The "Constitution") - -- Zod schemas for all protocols (ObjectQL, Kernel/System, ObjectUI) -- TypeScript type definitions -- JSON Schema generation -- Constants and enums -- **Zero runtime dependencies** (except Zod) - -```typescript -// packages/spec/src/ -├── data/ # ObjectQL schemas (Object, Field, Query, etc.) -├── ui/ # ObjectUI schemas (App, View, Dashboard, etc.) -├── system/ # System schemas (Manifest, Driver, Plugin, etc.) -├── automation/ # Workflow, Flow, Trigger schemas -├── ai/ # Agent, RAG, Model schemas -├── api/ # API contract schemas -├── auth/ # Authentication & Authorization schemas -└── shared/ # Common utilities -``` - -#### `@objectstack/core` -**Location**: `packages/core/` -**Role**: Microkernel Runtime - -- `ObjectKernel` - Plugin lifecycle manager -- `PluginContext` - Runtime context for plugins -- `Logger` - Universal logging (Pino-based) -- Service Registry (DI Container) -- Event Bus (Hook System) - -**Dependencies**: `@objectstack/spec`, `pino`, `zod` - -#### `@objectstack/types` -**Location**: `packages/types/` -**Role**: Shared Runtime Interfaces - -- Type definitions used across packages -- Runtime environment types -- Minimal, focused on shared contracts - -**Dependencies**: `@objectstack/spec` - -### Engine Packages - -#### `@objectstack/objectql` -**Location**: `packages/objectql/` -**Role**: ObjectQL Query Engine - -- ObjectQL core engine -- Schema registry -- Query compilation -- Driver management -- Protocol implementation - -**Dependencies**: `@objectstack/core`, `@objectstack/spec`, `@objectstack/types` - -#### `@objectstack/metadata` -**Location**: `packages/metadata/` -**Role**: Metadata Loading & Persistence - -- Metadata serialization/deserialization (JSON, YAML, TypeScript) -- File system operations (load, save, watch) -- Validation using Zod schemas -- ETag-based caching -- Import/export tools -- SchemaRegistry persistence bridge - -**Dependencies**: `@objectstack/spec`, `@objectstack/core`, `@objectstack/types`, `glob`, `js-yaml`, `chokidar` - -#### `@objectstack/runtime` -**Location**: `packages/runtime/` -**Role**: Runtime Utilities & Plugins - -- `DriverPlugin` - Generic driver wrapper -- `AppPlugin` - Application loader -- HTTP Server utilities -- REST API server -- Middleware system - -**Dependencies**: `@objectstack/core`, `@objectstack/spec`, `@objectstack/types` - -### Client Packages - -#### `@objectstack/client` -**Location**: `packages/client/` -**Role**: Official TypeScript Client SDK for ObjectStack Protocol - -**Features**: -- **Auto-Discovery**: Connects to ObjectStack server and auto-configures API endpoints -- **Typed Metadata**: Retrieve Object and View definitions with full TypeScript support -- **Metadata Caching**: ETag-based conditional requests for efficient metadata caching -- **Data Operations**: - - Advanced queries with filtering, sorting, and field selection - - CRUD operations (create, read, update, delete) - - Batch operations with transaction support (batch create/update/upsert/delete) - - Query builder with type-safe filters -- **View Storage**: Save, load, share, and manage custom UI view configurations -- **Error Handling**: Standardized error codes with retry guidance -- **HTTP Caching**: ETag support for optimized metadata requests - -**API Surface**: -- `client.connect()`: Initialize client with server discovery -- `client.meta.*`: Metadata operations (getObject, getCached, getView) -- `client.data.*`: Data operations (find, get, query, create, batch, update, delete) -- `client.views.*`: View storage operations (create, get, list, update, delete, share) - -**Dependencies**: `@objectstack/core`, `@objectstack/spec` - -#### `@objectstack/client-react` -**Location**: `packages/client-react/` -**Role**: React Hooks for ObjectStack Client SDK - -**Features**: -- **Data Hooks**: `useQuery`, `useMutation`, `usePagination`, `useInfiniteQuery` -- **Metadata Hooks**: `useObject`, `useView`, `useFields`, `useMetadata` -- **Context Management**: `ObjectStackProvider`, `useClient` -- **Type Safety**: Full TypeScript generics support for type-safe data -- **Auto-refetch**: Automatic data refetching and caching -- **Loading States**: Built-in loading and error state management - -**Dependencies**: `@objectstack/client`, `@objectstack/core`, `@objectstack/spec` -**Peer Dependencies**: `react` - -### Driver & Plugin Packages - -Drivers (`IDataDriver` implementations) live in `packages/drivers/*`; every other -official plugin lives in `packages/plugins/*`. - -#### `@objectstack/driver-memory` -**Location**: `packages/drivers/driver-memory/` -**Role**: In-Memory Driver (Reference Implementation) - -- Complete ObjectQL driver implementation -- Used for testing and prototyping -- Demonstrates driver contract - -**Dependencies**: `@objectstack/core`, `@objectstack/spec` - -#### `@objectstack/plugin-hono-server` -**Location**: `packages/plugins/plugin-hono-server/` -**Role**: HTTP Server Plugin - -- Hono-based HTTP server -- REST API endpoints -- Middleware support - -**Dependencies**: `@objectstack/core`, `@objectstack/spec`, `@objectstack/types`, `hono` - -### Tools Packages - -#### `@objectstack/cli` -**Location**: `packages/cli/` -**Role**: Command Line Interface - -- Project scaffolding -- Code generation -- Development tools -- Build & deployment utilities - -**Dependencies**: `@objectstack/spec`, `commander`, `chalk`, `tsx`, `zod` - ---- - -## Layer Architecture - -ObjectStack follows a **Three-Layer Protocol Stack**: - -``` -┌──────────────────────────────────────────────────┐ -│ Layer 3: ObjectUI (View) │ -│ ┌────────────────────────────────────────────┐ │ -│ │ Apps, Views, Dashboards, Reports │ │ -│ │ "How do users interact?" │ │ -│ └────────────────────────────────────────────┘ │ -│ Packages: @objectstack/client-react │ -└────────────────┬─────────────────────────────────┘ - │ REST API / GraphQL -┌────────────────▼─────────────────────────────────┐ -│ Layer 2: Kernel (Control) │ -│ ┌────────────────────────────────────────────┐ │ -│ │ Auth, Permissions, Workflows, Events │ │ -│ │ "Who can do what, when?" │ │ -│ └────────────────────────────────────────────┘ │ -│ Packages: @objectstack/runtime, │ -│ @objectstack/plugin-hono-server │ -└────────────────┬─────────────────────────────────┘ - │ ObjectQL Protocol -┌────────────────▼─────────────────────────────────┐ -│ Layer 1: ObjectQL (Data) │ -│ ┌────────────────────────────────────────────┐ │ -│ │ Objects, Fields, Queries, Drivers │ │ -│ │ "What is the data structure?" │ │ -│ └────────────────────────────────────────────┘ │ -│ Packages: @objectstack/objectql, │ -│ @objectstack/driver-* │ -└──────────────────────────────────────────────────┘ - -Foundation: -┌──────────────────────────────────────────────────┐ -│ @objectstack/core (Microkernel) │ -│ @objectstack/spec (Protocols) │ -│ @objectstack/types (Shared Types) │ -└──────────────────────────────────────────────────┘ -``` - -### Layer Boundaries - -| Layer | Knows About | Doesn't Know About | -|-------|-------------|-------------------| -| **ObjectQL** | Schema, fields, queries, drivers | Users, permissions, UI | -| **Kernel** | Auth, workflows, events | Data structure, UI layout | -| **ObjectUI** | Layout, navigation, actions | Business logic, storage | - ---- - -## Plugin System - -### Plugin Interface - -```typescript -interface Plugin { - name: string; // Reverse domain notation - version?: string; // Semantic version - dependencies?: string[]; // Plugin names this depends on - - init(ctx: PluginContext): Promise | void; - start?(ctx: PluginContext): Promise | void; - destroy?(): Promise | void; -} -``` - -### Built-in Plugins - -#### ObjectQLPlugin -**Name**: `com.objectstack.engine.objectql` -**Location**: `packages/objectql/src/plugin.ts` - -```typescript -Services Registered: -- 'objectql': ObjectQL engine instance -- 'protocol': Protocol implementation shim - -Lifecycle: -- init: Register ObjectQL as service -- start: Discover and register drivers and apps -``` - -#### DriverPlugin -**Name**: `com.objectstack.driver.{name}` -**Location**: `packages/runtime/src/driver-plugin.ts` - -```typescript -Services Registered: -- 'driver.{name}': Driver instance - -Lifecycle: -- init: Register driver service -- start: Log driver started -``` - -#### AppPlugin -**Name**: `com.objectstack.app.{name}` -**Location**: `packages/runtime/src/app-plugin.ts` - -```typescript -Services Registered: -- 'app.{name}': Manifest instance - -Lifecycle: -- init: Register app manifest as service -``` - -### Plugin Capability Declaration - -**Location**: `packages/spec/src/kernel/plugin-capability.zod.ts` - -Plugins declare capabilities through structured manifests: - -```typescript -interface PluginCapabilityManifest { - implements?: PluginCapability[]; // Protocols implemented - provides?: PluginInterface[]; // Services exposed - requires?: PluginDependency[]; // Required plugins - extensionPoints?: ExtensionPoint[]; // Extension hooks - extensions?: Extension[]; // Extensions contributed -} -``` - ---- - -## Dependency Graph - -### Core Dependencies - -``` -@objectstack/spec (Zod schemas, zero runtime deps except zod) - ↑ - ├── @objectstack/types - │ ↑ - │ └── (Shared by many packages) - │ - ├── @objectstack/core (Kernel + Logger) - │ ↑ - │ ├── @objectstack/objectql (Query Engine) - │ │ - │ ├── @objectstack/metadata (Metadata I/O) - │ │ ↑ - │ │ ├── @objectstack/runtime (Uses for manifest loading) - │ │ ├── @objectstack/cli (Uses for code generation) - │ │ └── @objectstack/objectql (Uses for registry persistence) - │ │ - │ ├── @objectstack/runtime (Plugins & HTTP) - │ │ ↑ - │ │ └── (Used by server plugins) - │ │ - │ ├── @objectstack/client - │ │ ↑ - │ │ └── @objectstack/client-react - │ │ - │ └── @objectstack/driver-memory - │ - ├── @objectstack/cli (Standalone tool) -``` - -### Dependency Rules - -1. **`@objectstack/spec` has ZERO dependencies** (except Zod) - - Pure protocol definitions - - Can be used standalone for type-checking - -2. **`@objectstack/core` depends only on `@objectstack/spec`** - - Minimal kernel - - No knowledge of ObjectQL or UI - -3. **`@objectstack/objectql` depends on `core` and `spec`** - - Pluggable into kernel - - Independent of UI layer - -4. **Plugins depend on `core` and optionally `objectql`** - - Never depend on other plugins directly - - Use service registry for runtime coupling - -5. **No circular dependencies** - - Enforced through topological sort - - Build-time validation - ---- - -## Design Decisions - -### 1. Microkernel vs Monolithic - -**Decision**: Use microkernel architecture - -**Rationale**: -- Business logic isolated in plugins -- Core remains stable -- Easy to swap implementations -- Better testability - -**Tradeoffs**: -- More complex setup -- Plugin discovery overhead -- Learning curve for plugin API - -### 2. Zod-First Schema Definition - -**Decision**: All schemas defined with Zod - -**Rationale**: -- Runtime validation -- TypeScript inference -- JSON Schema generation -- Single source of truth - -**Implementation**: -```typescript -// Define once with Zod -export const FieldSchema = z.object({ ... }); - -// TypeScript types inferred -export type Field = z.infer; - -// JSON Schema generated at build time -``` - -### 3. Reverse Domain Naming - -**Decision**: Use reverse domain notation for plugins - -**Rationale**: -- Global uniqueness -- Industry standard (OSGi, Eclipse, Android) -- Clear ownership -- Hierarchical organization - -**Examples**: -- `com.objectstack.engine.objectql` -- `com.objectstack.driver.postgres` -- `com.acme.crm.customer-management` - -### 4. Service Registry Pattern - -**Decision**: Use DI container for service discovery - -**Rationale**: -- Loose coupling -- Runtime flexibility -- Easy mocking for tests -- No hard dependencies - -**Alternative Considered**: Direct imports -**Rejected Because**: Creates tight coupling - -### 5. Event-Driven Communication - -**Decision**: Use hook/event system for inter-plugin communication - -**Rationale**: -- Decoupled communication -- Multiple subscribers -- Async handling -- Extensibility - -**Standard Events**: -```typescript -// Kernel lifecycle -'kernel:init' -'kernel:ready' -'kernel:shutdown' - -// Data lifecycle -'data:record:beforeCreate' -'data:record:afterCreate' -'data:record:beforeUpdate' -'data:record:afterUpdate' -``` - -### 6. Three-Layer Protocol Stack - -**Decision**: Separate QL, OS, UI into distinct layers - -**Rationale**: -- Separation of concerns -- Technology independence -- Parallel development -- Incremental migration - -**See Also**: [content/docs/concepts/architecture.mdx](content/docs/concepts/architecture.mdx) - -### 7. Monorepo Structure - -**Decision**: Use pnpm workspaces - -**Rationale**: -- Shared dependencies -- Atomic commits -- Easier refactoring -- Consistent versioning - -**Build Order**: -1. `@objectstack/spec` -2. `@objectstack/types`, `@objectstack/core` -3. `@objectstack/objectql`, `@objectstack/runtime` -4. Plugins and clients - -### 8. Plugin vs Package - -**Decision**: Not all packages are plugins - -**Rationale**: -- `@objectstack/spec` - Pure data, no runtime -- `@objectstack/cli` - Standalone tool -- `@objectstack/core` - Kernel, not a plugin - -**Plugin Packages**: Implement `Plugin` interface and can be registered with kernel - ---- - -## Package Naming Conventions - -### Package-Level Identifiers (Distribution) - -**Format**: `@objectstack/{category}-{name}` -**Style**: `kebab-case` -**Examples**: -- `@objectstack/driver-memory` -- `@objectstack/plugin-hono-server` -- `@objectstack/client-react` - -### Plugin Identifiers (Runtime) - -**Format**: `{domain}.{category}.{name}` -**Style**: `kebab-case` -**Examples**: -- `com.objectstack.engine.objectql` -- `com.objectstack.driver.postgres` -- `com.acme.crm.customer-management` - -### Code-Level Identifiers - -**Configuration Keys**: `camelCase` -```typescript -{ maxLength: 120, defaultValue: 'hello' } -``` - -**Data Values**: `snake_case` -```typescript -{ name: 'first_name', object: 'project_task' } -``` - ---- - -## Additional Resources - -### Architecture Decision Records (ADRs) - -Important architectural decisions are documented as ADRs in `docs/adr/`. - -**Metadata service architecture.** This section used to link -`docs/adr/0001-metadata-service-architecture.md`, deleted on 2026-02-11 in `9da8e3e72` -(together with ADR-0002 and the ADR `README.md`). The link is deliberately not repointed -at another record, because the decision it carried — *both ObjectQL and MetadataPlugin can -provide the metadata service, MetadataPlugin taking precedence and ObjectQL acting as -fallback* — is no longer what the code does. Today: - -- **MetadataPlugin is the sole provider** of the `metadata` service - (`packages/metadata/src/plugin.ts`). `ObjectQLPlugin` registers `objectql`, `data`, - `manifest` and `lifecycle` — never `metadata`. -- **ObjectQL is a consumer.** In `start()` it reads the `metadata` service, syncs - definitions into its own registry and subscribes to metadata events, and degrades to - that internal registry when no such service is present - (`packages/objectql/src/plugin.ts`). -- **The shared-interface principle survived, as a spec contract**: `IMetadataService` in - `packages/spec/src/contracts/metadata-service.ts`, with the slot declared as - `CoreServiceName 'metadata'` in `packages/spec/src/system/core-services.zod.ts`. -- **Repository, change-log and subscription mechanics** are recorded in - [ADR-0008: Metadata Repository, Change Log & Subscription](docs/adr/0008-metadata-repository-and-change-log.md). - -The single-provider decision itself has **no ADR record today** — ADR-0001 was deleted and -nothing replaced it. Re-homing it is a maintainer call; until then the contract and the two -plugin files above are the live source of truth. - -### Component-Specific Documentation - -`docs/METADATA_FLOW.md` no longer exists in this repository and no replacement was ever -written; the closest live description of how metadata flows from definition to runtime is -the "Metadata service architecture" walkthrough immediately above. - ---- - -## Future Considerations - -### Planned Enhancements - -1. **Plugin Versioning & Compatibility** - - SemVer range matching - - Breaking change detection - - Deprecation warnings - -2. **Plugin Registry & Hub** - - Centralized plugin discovery - - Quality scoring - - Security scanning - -3. **Hot Reload** - - Runtime plugin reload - - State preservation - - Development mode - -4. **Multi-Tenancy** - - Kernel per tenant - - Resource isolation - - Shared plugin instances - -5. **Enhanced Logging** - - Structured logging - - Distributed tracing - - Performance metrics - ---- - -## Related Documentation - -- [Development Roadmap](./ROADMAP.md) - Next-phase optimization & improvement plan -- [Three-Layer Stack](./content/docs/concepts/architecture.mdx) - How the Data, System, and UI protocols work together as one cohesive system -- [Design Principles](./content/docs/concepts/design-principles.mdx) - -Six more links used to live in this list — a Quick Reference Guide, a Package Dependency -Graph, a Studio Roadmap, and three `content/docs/developers/*` guides (MicroKernel -Architecture, Plugin Ecosystem, Writing Plugins). None of those files exist anywhere in -this repository today (Studio itself now lives in the separate `objectui` repository, so -no relative link from here can reach a Studio roadmap), and no replacement was ever -written, so the entries are removed rather than repointed at a guess. - ---- - -**Last Updated**: February 2026 -**Maintainers**: ObjectStack Core Team -**Status**: Living Document +The architecture is documented on the docs site, which is kept current with the code: +**[Protocol architecture — the four layers](https://objectstack.ai/docs/concepts/architecture)** +(source: [`content/docs/concepts/architecture.mdx`](content/docs/concepts/architecture.mdx)). The +long-form overview that used to live in this file described the tree of early 2026 and was no +longer maintained; it is in git history at commit +[`df8aac41`](https://github.com/objectstack-ai/objectstack/blob/df8aac41f2d9d14db04afdfe48511216419dafc0/ARCHITECTURE.md). diff --git a/CHANGELOG.md b/CHANGELOG.md index 09f2eefd293..ad7300b7c67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +> **Current release notes live in [`content/docs/releases/`](content/docs/releases).** This file +> keeps the historical entries below and is no longer extended. + All notable changes to the ObjectStack Protocol will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), @@ -1593,7 +1596,7 @@ Followup to M10.30a. Walked every Setup menu in a real tenant; produced verdict > deprecations/retirements, and additions to the authorable surface — so this file again > does what its header promises. Releases `4.0.2`–`9.11.0` remain documented in the > per-package changelogs. For every `10.x → 11.x` migration step see -> [docs/upgrading-to-11.md](./docs/upgrading-to-11.md); the compatibility gates that +> [docs/upgrading-to-11.md](https://github.com/objectstack-ai/objectstack/blob/df8aac41f2d9d14db04afdfe48511216419dafc0/docs/upgrading-to-11.md); the compatibility gates that > govern what may break and when are ADR-0059, and the upgrade-communication contract is > ADR-0087. @@ -1706,7 +1709,7 @@ never as per-surface hint blocks (#2521). ## [11.1.0] — 2026-06-28 Completes the 11.0 breaking line (see -[docs/upgrading-to-11.md](./docs/upgrading-to-11.md)). +[docs/upgrading-to-11.md](https://github.com/objectstack-ai/objectstack/blob/df8aac41f2d9d14db04afdfe48511216419dafc0/docs/upgrading-to-11.md)). ### Removed - **`DriverInterface` type alias** (deprecated in 11.0) — use `IDataDriver` (same @@ -1726,7 +1729,7 @@ Completes the 11.0 breaking line (see ## [11.0.0] — 2026-06-27 **Major.** Every breaking change of the 11 line, each with a concrete migration, is in -[docs/upgrading-to-11.md](./docs/upgrading-to-11.md) (also covering the package-level +[docs/upgrading-to-11.md](https://github.com/objectstack-ai/objectstack/blob/df8aac41f2d9d14db04afdfe48511216419dafc0/docs/upgrading-to-11.md) (also covering the package-level breaks outside the spec surface: Hono-only HTTP adapters, `client-react` canonical query fields, `OS_*` env renames). diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index b2e0c7bec9a..b16e55b7a05 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,6 +1,6 @@ # Release Notes -> **📓 This file is historical.** Current, developer-facing release notes live in +> **📓 This file is historical and frozen — nothing new is added to it.** Current, developer-facing release notes live in > the curated per-major pages under [`content/docs/releases/`](content/docs/releases) > — they lead with breaking changes + migration and cover backend **and** Console > (frontend) per platform version. For exhaustive per-package detail, see each @@ -8,10 +8,10 @@ > historical reference; see `docs/releases-maintenance.md` for how release history > is maintained. -> **v5.0 (2026): `project` → `environment`.** The runtime concept formerly called *Project* (per-tenant business workspace; Org/Project/Branch hierarchy) is now called *Environment* throughout the codebase: CLI flags (`--environment`/`-e`), HTTP paths (`/api/v1/environments/:environmentId/...`), headers (`X-Environment-Id`), env vars (`OS_ENVIRONMENT_ID`), exported symbols (`createSystemEnvironmentPlugin`, `SYSTEM_ENVIRONMENT_ID`), DB columns (`environment_id`), and JSON schemas (`EnvironmentArtifact`) all use the new term with no aliases or deprecation shims. The word "project" elsewhere in this document still refers to the npm/monorepo sense (i.e., the framework as a software project). See `.changeset/v5-project-to-environment-rename.md` for the full breaking-change list and ADR-0006 for the rationale. +> **v5.0 (2026): `project` → `environment`.** The runtime concept formerly called *Project* (per-tenant business workspace; Org/Project/Branch hierarchy) is now called *Environment* throughout the codebase: CLI flags (`--environment`/`-e`), HTTP paths (`/api/v1/environments/:environmentId/...`), headers (`X-Environment-Id`), env vars (`OS_ENVIRONMENT_ID`), exported symbols (`createSystemEnvironmentPlugin`, `SYSTEM_ENVIRONMENT_ID`), DB columns (`environment_id`), and JSON schemas (`EnvironmentArtifact`) all use the new term with no aliases or deprecation shims. The word "project" elsewhere in this document still refers to the npm/monorepo sense (i.e., the framework as a software project). See ADR-0006 for the rationale. -## v4.0.4 — Release Readiness: Documentation Alignment _(in progress)_ +## v4.0.4 — Release Readiness: Documentation Alignment ### 🎯 Purpose diff --git a/content/docs/api/client-sdk.mdx b/content/docs/api/client-sdk.mdx index 0a6ade78f5e..9de1c094b05 100644 --- a/content/docs/api/client-sdk.mdx +++ b/content/docs/api/client-sdk.mdx @@ -577,7 +577,7 @@ The `find` method accepts an options object with **canonical** (recommended) fie | `expand` | `Record` or `string[]` | Relation loading (JOIN) | `{ owner: {} }` | -**Canonical names recommended:** `find()` accepts the canonical names above; the legacy aliases (`select`, `filter`/`filters`, `sort`, `top`, `skip`) still work for backward compatibility, but new code should use the canonical names. (`@objectstack/client-react`'s `useQuery`/`useInfiniteQuery` hooks are stricter — the legacy aliases were removed there in v11; see `docs/upgrading-to-11.md`.) +**Canonical names recommended:** `find()` accepts the canonical names above; the legacy aliases (`select`, `filter`/`filters`, `sort`, `top`, `skip`) still work for backward compatibility, but new code should use the canonical names. (`@objectstack/client-react`'s `useQuery`/`useInfiniteQuery` hooks are stricter — the legacy aliases were removed there in v11.) ### Batch Options diff --git a/docs/DX_ROADMAP.md b/docs/DX_ROADMAP.md deleted file mode 100644 index f47e162cdab..00000000000 --- a/docs/DX_ROADMAP.md +++ /dev/null @@ -1,232 +0,0 @@ -# ObjectStack — Developer Experience (DX) Roadmap - -> **Last Updated:** 2026-02-13 -> **Scope:** Post v3.0 — Focused entirely on Developer Experience -> **Based On:** Full codebase audit — 175 schemas, 195 test files (5,269 tests), 150+ doc pages, 4 examples, 14 packages -> **Previous:** `ROADMAP.md` (v3.0 Phases 5–11 ✅ Complete) - ---- - -## Executive Summary - -ObjectStack v3.0 delivered a production-grade protocol spec with comprehensive type safety, test coverage, security hardening, and build tooling. The **next frontier is developer adoption** — making it effortless for developers to discover, learn, and build with the platform. - -This roadmap prioritizes improvements based on the **"Time to First Wow"** metric: how quickly a new developer goes from `npm init` to a running application with data, UI, and API. - -### Current DX Assessment (Feb 2026 Audit) - -| Area | Score | Notes | -|------|-------|-------| -| **Type Safety** | ⭐⭐⭐⭐⭐ | Zod-first, 7,111 `.describe()`, full inference, branded types | -| **Schema Completeness** | ⭐⭐⭐⭐⭐ | 175 schemas, 1,470 JSON Schemas, OpenAPI 3.1, bundled `objectstack.json` | -| **Test Coverage** | ⭐⭐⭐⭐⭐ | 195 test files (5,269 tests), 100%+ schema coverage | -| **IDE Autocomplete** | ⭐⭐⭐⭐ | Bundled `objectstack.json`, `.describe()` tooltips, subpath exports | -| **Error Messages** | ⭐⭐⭐⭐⭐ | Custom Zod error map, "Did you mean?" fuzzy suggestions, `safeParsePretty()` | -| **Helper Functions** | ⭐⭐⭐⭐⭐ | 6 `define*` helpers + `ObjectSchema.create()` + `Field.*` + strict `defineStack()` | -| **Getting Started** | ⭐⭐⭐⭐ | Docs, StackBlitz playground; no video walkthrough yet | -| **Reference Docs** | ⭐⭐⭐⭐⭐ | Field type gallery ✅, error catalog ✅, query cheat sheet ✅, Contracts ✅ | -| **Examples** | ⭐⭐⭐⭐ | 4 examples with READMEs, "How to Run" sections, StackBlitz link | -| **Migration Story** | ⭐⭐⭐ | V3 migration guide exists; no automated codemod tooling | - ---- - -## Completed Phases - -
-Phase 1: First Five Minutes (Onboarding) ✅ 9/10 - -- [x] Create StackBlitz starter template from `app-todo` -- [x] Add "Try Online" button to spec README.md and docs site hero -- [x] Add "How to Run" section to each example README (app-todo, hotcrm, server, plugin-bi) -- [x] Add prerequisites section to getting-started docs -- [x] Create first-run troubleshooting page -- [x] Implement `create-objectstack` CLI wizard with 3 templates -- [ ] Record 5-minute getting-started video -- [x] Fix `examples/README.md`: remove `minimal-auth` ghost reference, update metadata -- [x] Fix `plugin-bi` example: add README.md, add package.json scripts -- [x] Fix `server` (formerly app-host) README: use `pnpm dev` instead of `npm run dev` - -
- -
-Phase 2: Schema DX Helpers ✅ 9/9 - -- [x] Enhance `ObjectSchema.create()` with auto-label, common fields, and validation -- [x] Implement `defineView()` with column type inference -- [x] Implement `defineApp()` with navigation builder -- [x] Implement `defineFlow()` with step type inference -- [x] Create custom Zod error map with contextual messages -- [x] Add "Did you mean?" suggestions for FieldType typos -- [x] Create pretty-print validation error formatter for CLI -- [x] Add branded types for ObjectName, FieldName, ViewName -- [x] Add strict cross-reference validation mode to `defineStack()` - -
- -
-Phase 3: Documentation & Reference ✅ 16/16 - -- [x] Create field type gallery page with all 48 types -- [x] Create per-field-type configuration reference tables -- [x] Create error code catalog with 41+ error codes -- [x] Create HTTP status mapping reference -- [x] Create protocol relationship diagram (visual) -- [x] Create query syntax cheat sheet -- [x] Add wire format JSON examples to protocol docs -- [x] Create common patterns guide (top 10 patterns) -- [x] Create troubleshooting / FAQ page -- [x] Create plugin development tutorial -- [x] Populate Contracts docs section -- [x] Add field type decision tree ("Which field type?") -- [x] Add client-side error handling guide -- [x] Add server-side error handling guide -- [x] Add data flow diagram guide (defineStack → kernel → driver → DB) -- [x] Add security permissions matrix - -
- ---- - -## Phase 4: CLI & Tooling DX — 2 weeks 🔄 Active - -> **Goal:** The CLI is a developer's best friend — it catches mistakes before runtime. -> **Metric:** `objectstack doctor` catches 90%+ of common configuration mistakes. - -### 4.1 CLI Enhancements - -| Task | Details | Priority | Status | -|------|---------|----------|--------| -| `objectstack diff` | Compare two spec versions, detect breaking changes, output changelog | 🔴 High | ❌ | -| `objectstack doctor` improvements | Detect: circular deps, missing test files, deprecated usage, unused objects, orphan views | 🔴 High | ❌ | -| `objectstack lint` | Style checker: snake_case names, required fields, label conventions | 🟡 Medium | ❌ | -| `objectstack explain ` | Print human-readable explanation of any schema with examples | 🟡 Medium | ❌ | -| `objectstack migrate` | Auto-generate migration scripts for schema changes (add/remove fields) | 🟢 Low | ❌ | - -### 4.2 IDE Integration - -| Task | Details | Priority | Status | -|------|---------|----------|--------| -| VSCode extension | Syntax highlighting, autocomplete, inline validation | 🔴 High | ✅ Done | -| JSON Schema for `objectstack.config.ts` | IDE autocomplete when editing config file | 🔴 High | ✅ Done | -| Diagnostic language server | Real-time validation with inline error squiggles | 🟡 Medium | ❌ | -| Code actions (quick fixes) | Auto-fix: add missing `label`, fix snake_case, add required `options` | 🟡 Medium | ❌ | - -### 4.3 Code Generation - -| Task | Details | Priority | Status | -|------|---------|----------|--------| -| `objectstack generate client --lang ts` | Type-safe client SDK from stack definition | 🟡 Medium | ❌ | -| `objectstack generate openapi` | OpenAPI spec from stack definition | 🟡 Medium | ❌ | -| `objectstack generate migration` | Database migration from object diff | 🟡 Medium | ❌ | -| `objectstack generate seed` | Generate seed data from object schemas | 🟢 Low | ❌ | - -### 4.4 Codemod & Migration Tooling - -| Task | Details | Priority | Status | -|------|---------|----------|--------| -| `objectstack codemod v2-to-v3` | Automated AST transform for v2 → v3 breaking changes | 🟡 Medium | ❌ | -| Deprecation scanner | CLI command to detect usage of `@deprecated` items | 🟡 Medium | ❌ | -| Config validator | Deep validation of `objectstack.config.ts` with cross-reference checks | 🟡 Medium | ❌ | - -### Phase 4 Checklist - -- [ ] Implement `objectstack diff` with breaking change detection -- [ ] Enhance `objectstack doctor` (circular deps, missing tests, deprecated usage) -- [ ] Implement `objectstack lint` for naming conventions -- [ ] Implement `objectstack explain` for schema documentation -- [x] Create VSCode extension with autocomplete and validation -- [x] Add JSON Schema for `objectstack.config.ts` IDE support -- [ ] Implement `objectstack generate client` for typed SDK generation -- [ ] Implement `objectstack generate migration` for schema diffs -- [ ] Add deprecation scanner to CLI - ---- - -## Phase 6: Ecosystem & Community — Ongoing 📋 Planned - -> **Goal:** Build a thriving ecosystem of plugins, examples, and community contributions. -> **Metric:** 10+ community plugins published, 100+ GitHub stars. - -### 6.1 Plugin Marketplace - -| Task | Details | Priority | -|------|---------|----------| -| Plugin registry API | REST API for discovering, searching, and downloading plugins | 🟡 Medium | -| Plugin quality scoring | Automated scoring: tests, docs, types, security scan | 🟡 Medium | -| Plugin starter template | `objectstack generate plugin` with test setup, CI, publishing | 🔴 High | - -### 6.2 Example Gallery - -| Task | Details | Priority | -|------|---------|----------| -| 10+ curated examples | SaaS, eCommerce, Healthcare, Education, Project Management, etc. | 🟡 Medium | -| Example difficulty rating | Beginner / Intermediate / Advanced badges | 🟡 Medium | -| "Fork & Customize" flow | One-click fork of any example into user's own project | 🟢 Low | - -### 6.3 Community Infrastructure - -| Task | Details | Priority | -|------|---------|----------| -| Discord community | Developer support channel, showcase, RFC discussions | 🟡 Medium | -| Blog / Changelog | Regular updates on new features, best practices, community highlights | 🟡 Medium | -| Contributor recognition | Contributors page, "first PR" badges, hall of fame | 🟢 Low | - -### Phase 6 Checklist - -- [ ] Implement plugin registry API (search, publish, download) -- [ ] Create plugin starter template with CI and publishing -- [ ] Add plugin quality scoring system -- [ ] Create 10+ curated example applications -- [ ] Add example difficulty ratings -- [ ] Set up Discord community with support channels -- [ ] Create blog/changelog system for regular updates - ---- - -## Timeline Summary - -``` -2026 Q1 (Complete) - ├── Phase 1: First Five Minutes [2 weeks] ✅ 9/10 — Playground, quick-start, example fixes - ├── Phase 2: Schema DX Helpers [2 weeks] ✅ 9/9 — define* helpers, error map, branded types - └── Phase 3: Documentation & Reference [3 weeks] ✅ 16/16 — Field gallery, error catalog, contracts - -2026 Q2 (Tooling Sprint) - ├── Phase 4: CLI & Tooling DX [2 weeks] 🔄 Active (2/10 done) - └── Phase 5: Studio as DX Hub [3 weeks] 📋 Planned - -2026 Q3+ (Ecosystem Sprint) - └── Phase 6: Ecosystem & Community [Ongoing] 📋 Planned -``` - ---- - -## Success Criteria - -| Metric | v3.0 (Current) | Phase 4 | Phase 5 | Phase 6 | -|--------|----------------|---------|---------|---------| -| Time to First App | ~30 min | < 10 min | < 5 min | < 3 min | -| Documentation coverage | ~95% | 95%+ | 98% | 100% | -| Interactive examples | 1 (StackBlitz) | 2+ | 3+ | 10+ | -| Community plugins | 0 | 0 | 2+ | 10+ | -| CLI diagnostic commands | 2 | 6 | 6 | 8+ | -| IDE autocomplete coverage | JSON Schema + VSCode ext | + Language Server | Full | Full | -| Helper functions (`define*`) | 6 | 6+ | 6+ | 8+ | -| Test files / Tests | 195 / 5,269 | 195+ / 5,300+ | 200+ / 5,500+ | 210+ / 6,000+ | -| Example quality | 4 working | 4+ | 6+ | 10+ | - ---- - -## Relationship to Other Plans - -| Document | Focus | Status | -|----------|-------|--------| -| `ROADMAP.md` | v3.0 complete + v4.0 enterprise readiness | ✅ v3.0 Complete · 📋 v4.0 Planning | -| `apps/studio/ROADMAP.md` | Studio IDE visual features (Phases 0–8) | 🔄 Active | -| **`DX_ROADMAP.md` (this file)** | **Developer Experience & Adoption** | 🔄 Active — Phase 4 | - ---- - -**Last Updated:** 2026-02-13 -**Maintainers:** ObjectStack Core Team -**Status:** ✅ Phase 1–3 Complete | 🔄 Phase 4 Active | 📋 Phase 5–6 Planned diff --git a/docs/NEXT_STEP.md b/docs/NEXT_STEP.md deleted file mode 100644 index 2fc0915a37b..00000000000 --- a/docs/NEXT_STEP.md +++ /dev/null @@ -1,239 +0,0 @@ -# ObjectStack — Project NEXT_STEP - - -## v4.0 — Enterprise Readiness - -> **Target:** v4.0.0 -> **Timeline:** 2026 Q2–Q3 (~13 weeks) -> **Based On:** [`ENTERPRISE_ASSESSMENT.md`](./ENTERPRISE_ASSESSMENT.md) — benchmark against Salesforce, ServiceNow, SAP, Dynamics 365 -> **Goal:** Close 23 critical enterprise gaps to achieve ~95% Salesforce parity and ~90% ServiceNow parity. - -### Enterprise Maturity Scoring (v3.0 → v4.0 Target) - -| Domain | v3.0 Score | Key Gaps | v4.0 Target | -|--------|-----------|----------|------------| -| **Data Model** | ⭐⭐⭐⭐ | Expression language, record types, custom metadata | ⭐⭐⭐⭐⭐ | -| **UI / Forms** | ⭐⭐⭐½ | Page layout engine, document generation, portal | ⭐⭐⭐⭐½ | -| **Automation** | ⭐⭐⭐⭐ | SLA engine, assignment rules, scheduled jobs | ⭐⭐⭐⭐⭐ | -| **Security** | ⭐⭐⭐⭐ | Audit trail API, delegated admin | ⭐⭐⭐⭐½ | -| **System / DevOps** | ⭐⭐⭐ | Deployment protocol, sandbox, fiscal calendar | ⭐⭐⭐⭐ | -| **AI / Intelligence** | ⭐⭐⭐⭐ | Predictive analytics, model governance | ⭐⭐⭐⭐½ | - ---- - -### Stage 1 — v4.0-alpha: Core Protocol Expansion (6 weeks) - -#### Phase 12: Data Model Completeness — 3 weeks - -> Close all critical data model gaps vs. Salesforce/ServiceNow. - -| # | Task | Priority | New File | -|---|------|----------|----------| -| 12.1 | Expression Language Spec (functions, type system, variables) | 🔴 Critical | `data/expression.zod.ts` | -| 12.2 | Record Types (business process variants per object) | 🔴 Critical | Add to `data/object.zod.ts` | -| 12.3 | Custom Metadata Types (deployable config records) | 🔴 Critical | `data/custom-metadata.zod.ts` | -| 12.4 | Duplicate Detection Rules | 🟡 High | `data/duplicate-rule.zod.ts` | -| 12.5 | Multi-Currency Management (exchange rates, corporate currency) | 🟡 High | `data/currency.zod.ts` | -| 12.6 | Data Import/Export Wizard Protocol | 🟡 High | `data/data-import.zod.ts` | - -**Checklist:** - -- [ ] Create expression language spec with function catalog, type system, and system variables -- [ ] Add record types to object schema with picklist filtering and layout mapping -- [ ] Create custom metadata types for deployable configuration records -- [ ] Create duplicate detection rules with fuzzy/exact/phonetic matching -- [ ] Create multi-currency management with exchange rates and conversion -- [ ] Create data import/export wizard protocol with field mapping and validation - -#### Phase 13: UI & Reporting Enhancement — 3 weeks - -> Match Salesforce page layouts and reporting capabilities. - -| # | Task | Priority | New File | -|---|------|----------|----------| -| 13.1 | Page Layout / Form Layout Engine | 🔴 Critical | `ui/page-layout.zod.ts` | -| 13.2 | Document Generation Templates (PDF, DOCX) | 🟡 High | `ui/document-template.zod.ts` | -| 13.3 | Report Scheduling & Subscriptions | 🟡 High | Enhance `ui/report.zod.ts` | -| 13.4 | Dashboard Drill-Down & Drill-Through | 🟡 High | Enhance `ui/dashboard.zod.ts` | -| 13.5 | Portal / Community Protocol | 🟡 High | `ui/portal.zod.ts` (rebuild **with a runtime**; the prior no-op stub was pruned per #3464) | -| 13.6 | Advanced Report Features (formulas, conditional formatting, snapshots) | 🟡 Medium | Enhance `ui/report.zod.ts` | - -**Checklist:** - -- [ ] Create page layout engine with sections, columns, related lists, compact layout -- [ ] Create document generation templates (PDF/DOCX/HTML) with variable binding -- [ ] Add report scheduling and subscription delivery -- [ ] Add dashboard drill-down with dynamic filter passing -- [ ] Create portal protocol for external user access (customer/partner/vendor) -- [ ] Add conditional formatting, report formulas, and analytic snapshots - ---- - -### Stage 2 — v4.0-beta: Automation & Operations (4 weeks) - -#### Phase 14: Automation Maturity — 2 weeks - -> Close SLA engine and assignment rule gaps for ITSM/customer service. - -| # | Task | Priority | New File | -|---|------|----------|----------| -| 14.1 | SLA / Entitlement Engine (milestones, business hours) | 🔴 Critical | `automation/sla.zod.ts` | -| 14.2 | Queue / Assignment Rules (routing, round-robin, skill-based) | 🟡 High | `automation/assignment-rule.zod.ts` | -| 14.3 | Scheduled Job Protocol (general-purpose recurring tasks) | 🔴 Critical | `automation/scheduled-job.zod.ts` | -| 14.4 | Inbound Capture Protocol (email-to-case, web-to-lead) | 🟡 High | `integration/inbound-capture.zod.ts` | - -**Checklist:** - -- [ ] Create SLA engine with milestones, business hours, escalation, and pause conditions -- [ ] Create queue and assignment rules with round-robin, skill-based, and load-balanced routing -- [ ] Create standalone scheduled job protocol with dependency chains and concurrency control -- [ ] Create inbound capture protocol for email/web/social record creation - -#### Phase 15: System & DevOps — 2 weeks - -> Enable enterprise CI/CD for metadata with structured deployment. - -| # | Task | Priority | New File | -|---|------|----------|----------| -| 15.1 | Deployment / Change Management Protocol | 🔴 Critical | `system/deployment.zod.ts` | -| 15.2 | Sandbox / Environment Management | 🔴 Critical | `system/sandbox.zod.ts` | -| 15.3 | Fiscal Year / Business Calendar | 🟡 High | `system/fiscal-calendar.zod.ts` | -| 15.4 | Audit Trail Query Protocol | 🟡 High | Enhance `security/audit.zod.ts` | -| 15.5 | Delegated Administration Protocol | 🟡 High | `security/delegated-admin.zod.ts` | - -**Checklist:** - -- [x] Create deployment protocol with packages, validation, rollback, and history — ✅ `system/deploy-bundle.zod.ts` (DeployBundle, MigrationPlan, DeployDiff, DeployValidationResult) -- [ ] Create sandbox management with metadata/data cloning and PII masking -- [ ] Create fiscal year and business calendar protocol -- [ ] Enhance audit trail with structured query protocol -- [ ] Create delegated administration protocol with scoped capabilities - ---- - -### Stage 3 — v4.0-GA: Intelligence & Contracts (3 weeks) - -#### Phase 16: AI & Intelligence — 2 weeks - -> Match Salesforce Einstein and ServiceNow Predictive Intelligence. - -| # | Task | Priority | New File | -|---|------|----------|----------| -| 16.1 | Predictive Analytics Integration (scoring, forecasting) | 🟡 High | Enhance `ai/predictive.zod.ts` | -| 16.2 | AI Model Governance (bias, explainability, audit) | 🟡 High | `ai/governance.zod.ts` | -| 16.3 | Process Mining Protocol | 🟡 Medium | `ai/process-mining.zod.ts` | -| 16.4 | Recommendation Engine Protocol | 🟡 Medium | `ai/recommendation.zod.ts` | - -**Checklist:** - -- [ ] Enhance predictive analytics with object-level prediction definitions and drift monitoring -- [ ] Create AI governance protocol with bias detection, explainability, and audit logging -- [ ] Create process mining protocol for workflow optimization insights -- [ ] Create recommendation engine protocol for next-best-action suggestions - -#### Phase 17: Service Contract Expansion — 1 week - -> Complete the service contract layer for all new protocols. - -| # | Task | Priority | New File | -|---|------|----------|----------| -| 17.1 | IAuditService contract | 🟡 High | `contracts/audit-service.ts` | -| 17.2 | IDeploymentService contract | 🟡 High | `contracts/deployment-service.ts` | -| 17.3 | ISLAService contract | 🟡 High | `contracts/sla-service.ts` | -| 17.4 | ISchedulerService contract | 🟡 Medium | `contracts/scheduler-service.ts` | -| 17.5 | IDocumentService contract | 🟡 Medium | `contracts/document-service.ts` | -| 17.6 | IPortalService contract | 🟡 Medium | `contracts/portal-service.ts` | - -**Checklist:** - -- [ ] Create IAuditService contract for audit trail querying and management -- [x] Create IDeploymentService contract for package deployment and rollback — ✅ `contracts/deploy-pipeline-service.ts` (IDeployPipelineService) + `contracts/schema-diff-service.ts` (ISchemaDiffService) -- [ ] Create ISLAService contract for SLA evaluation and escalation -- [ ] Create ISchedulerService contract for scheduled job management -- [ ] Create IDocumentService contract for document generation -- [ ] Create IPortalService contract for external user portal management - ---- - -### v4.0 Timeline - -``` -Stage 1 — v4.0-alpha (2026 Q2, 6 weeks) - ├── Phase 12: Data Model Completeness [3 weeks] → Expression language, record types, custom metadata - └── Phase 13: UI & Reporting Enhancement [3 weeks] → Page layouts, document templates, portal - -Stage 2 — v4.0-beta (2026 Q3, 4 weeks) - ├── Phase 14: Automation Maturity [2 weeks] → SLA engine, assignment rules, scheduled jobs - └── Phase 15: System & DevOps [2 weeks] → Deployment, sandbox, audit trail - -Stage 3 — v4.0-GA (2026 Q3–Q4, 3 weeks) - ├── Phase 16: AI & Intelligence [2 weeks] → Predictive analytics, model governance - └── Phase 17: Service Contracts [1 week] → 6 new service interfaces - -Total: ~13 weeks (3 months) -New schemas: ~18 files + ~12 enhancements -New tests: ~18 files + ~500 tests -New contracts: 6 service interfaces -``` - -### v4.0 Success Criteria - -| Metric | v3.0 (Current) | v4.0 (Target) | -|--------|----------------|---------------| -| Spec schema files | 175 | ~193 (+18) | -| Spec test files | 195 | ~213 (+18) | -| Spec test count | 5,269 | ~5,769 (+500) | -| Service contracts | 25 | 31 (+6) | -| Enterprise gap count | 23 critical/high | 0 critical, < 5 medium | -| Salesforce parity | ~75% | ~95% | -| ServiceNow parity | ~70% | ~90% | - ---- - -## Parallel Tracks - -### Developer Experience — [`DX_ROADMAP.md`](./DX_ROADMAP.md) - -| Phase | Title | Status | -|-------|-------|--------| -| 1 | First Five Minutes (Onboarding) | ✅ Complete (9/10) | -| 2 | Schema DX Helpers | ✅ Complete | -| 3 | Documentation & Reference | ✅ Complete (16/16) | -| 4 | CLI & Tooling DX | 🔄 Active | -| 5 | Studio as DX Hub | 📋 Planned | -| 6 | Ecosystem & Community | 📋 Planned | - -### Studio Visual IDE — [`apps/studio/ROADMAP.md`](./apps/studio/ROADMAP.md) - -| Phase | Title | Status | -|-------|-------|--------| -| 0 | Foundation Hardening (v2.1) | 📋 Planned | -| 1 | Data Protocol Designers (v2.2) | 📋 Planned | -| 2 | UI Protocol Designers (v2.3) | 📋 Planned | -| 3 | Automation Protocol (v2.4) | 📋 Planned | -| 4 | Security & Identity (v2.5) | 📋 Planned | -| 5 | AI & Intelligence (v2.6) | 📋 Planned | -| 6 | API & Integration (v2.7) | 📋 Planned | -| 7 | System & DevOps (v2.8) | 📋 Planned | -| 8 | Studio Platform Evolution (v3.0) | 📋 Planned | - ---- - -## Related Documents - -| Document | Location | Status | -|----------|----------|--------| -| Enterprise Assessment | `ENTERPRISE_ASSESSMENT.md` | 📋 v4.0 Reference | -| DX Roadmap | `DX_ROADMAP.md` | 🔄 Active (Phase 4–6) | -| Studio Roadmap | `apps/studio/ROADMAP.md` | 🔄 Active (Phase 0–8) | -| Architecture | `ARCHITECTURE.md` | ✅ Current | -| V3 Migration Guide | `packages/spec/V3_MIGRATION_GUIDE.md` | ✅ Current | -| Protocol Registry | `packages/spec/PROTOCOL_MAP.md` | ✅ Current | -| Release Notes | `RELEASE_NOTES.md` | ✅ Current | -| Changelog | `CHANGELOG.md` | ✅ Current | - ---- - -**Last Updated:** 2026-02-13 -**Maintainers:** ObjectStack Core Team -**Status:** ✅ v3.0 Released | 📋 v4.0 Enterprise Readiness — Planning diff --git a/docs/PLATFORM_GAPS_FROM_TEMPLATES.md b/docs/PLATFORM_GAPS_FROM_TEMPLATES.md index 01cad6cefcf..b5904e83f96 100644 --- a/docs/PLATFORM_GAPS_FROM_TEMPLATES.md +++ b/docs/PLATFORM_GAPS_FROM_TEMPLATES.md @@ -4,7 +4,7 @@ > > **维护约定**:此后每次开发模板/示例应用时,凡是发现"模板作者无法自行解决、需要平台修复"的问题,**都追加到本文档**,不要散落在各模板 README 中。 > -> 相关文档:`HARDENING.md`、`OBSERVABILITY.md`、`DX_ROADMAP.md`、`PLUGIN_ECOSYSTEM_MAP.md`。 +> 相关文档:`HARDENING.md`、`OBSERVABILITY.md`。 ## TL;DR — 按严重程度排序 diff --git a/docs/PLUGIN_ECOSYSTEM_MAP.md b/docs/PLUGIN_ECOSYSTEM_MAP.md deleted file mode 100644 index 6cb1ccd0591..00000000000 --- a/docs/PLUGIN_ECOSYSTEM_MAP.md +++ /dev/null @@ -1,242 +0,0 @@ -# ObjectStack Plugin Ecosystem Map - -``` - ┌─────────────────────────────────────────┐ - │ ObjectStack Platform Core │ - │ (137 Zod Protocol Modules) │ - └──────────────┬──────────────────────────┘ - │ - ┌──────────────────────┼──────────────────────┐ - │ │ │ - ┌───────▼────────┐ ┌───────▼────────┐ ┌───────▼────────┐ - │ ObjectQL │ │ ObjectOS │ │ ObjectUI │ - │ (Data Layer) │ │ (System Layer) │ │ (View Layer) │ - │ 33 Protocols │ │ 35 Protocols │ │ 10 Protocols │ - └───────┬────────┘ └───────┬────────┘ └───────┬────────┘ - │ │ │ - └─────────────────────┼──────────────────────┘ - │ - ┌─────────────────────────────┴─────────────────────────────┐ - │ Plugin Ecosystem │ - └─────────────────────────────┬─────────────────────────────┘ - │ - ┌─────────────────────────────┴─────────────────────────────┐ - │ │ - │ 🔴 P0 - Immediate (Q1 2026) │ - │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ - │ │ CRM │ │ Project │ │ AI │ │ - │ │ Foundation │ │ Management │ │ Customer │ │ - │ │ │ │ │ │ Support │ │ - │ │ Score: 9.5 │ │ Score: 8.8 │ │ Score: 9.0 │ │ - │ └──────────────┘ └──────────────┘ └──────────────┘ │ - │ │ - └─────────────────────────────────────────────────────────────┘ - │ - │ 🟠 P1 - Near Term (Q2 2026) - │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ - │ │ HRM │ │ BI │ │ Document │ - │ │ │ │ Analytics │ │ Management │ - │ │ Score: 8.2 │ │ Score: 8.5 │ │ Score: 8.0 │ - │ └──────────────┘ └──────────────┘ └──────────────┘ - │ - └─────────────────────────────────────────────────────────────┘ - │ - │ 🟡 P2 - Mid Term (Q3-Q4 2026) - │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ - │ │ Healthcare │ │ Financial │ │Manufacturing │ - │ │ EMR │ │ Risk │ │ MES │ - │ │ Score: 8.0 │ │ Score: 8.0 │ │ Score: 7.4 │ - │ └──────────────┘ └──────────────┘ └──────────────┘ - │ - └─────────────────────────────────────────────────────────────┘ - - -┌────────────────────────────────────────────────────────────────────────┐ -│ Plugin Development Framework │ -├────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 📦 Plugin Package Structure │ -│ ──────────────────────────────── │ -│ @objectstack/plugin-{name}/ │ -│ ├── src/ │ -│ │ ├── objects/ # Business objects (.object.ts) │ -│ │ ├── views/ # UI views (.view.ts) │ -│ │ ├── flows/ # Workflows (.flow.ts) │ -│ │ ├── dashboards/ # Dashboards (.dashboard.ts) │ -│ │ ├── agents/ # AI agents (.agent.ts) │ -│ │ └── index.ts # Plugin entry point │ -│ ├── objectstack.config.ts # Manifest │ -│ └── README.md │ -│ │ -│ 🔧 Available Building Blocks │ -│ ──────────────────────────────── │ -│ Data Layer (ObjectQL) │ -│ • 15+ field types (text, number, lookup, formula...) │ -│ • Advanced queries (filters, aggregations, joins) │ -│ • Data validation and hooks │ -│ • SQL/NoSQL/External data sources │ -│ │ -│ UI Layer (ObjectUI) │ -│ • 12 view types (grid, kanban, gantt, calendar...) │ -│ • 12 widget types (kpi, chart, list...) │ -│ • Custom themes and branding │ -│ • Responsive mobile support │ -│ │ -│ AI Layer (AI Protocols) │ -│ • Agents with custom tools │ -│ • RAG knowledge retrieval │ -│ • Natural language queries │ -│ • Predictive analytics │ -│ • Multi-model orchestration │ -│ │ -│ Automation Layer │ -│ • Visual workflows │ -│ • Approval processes │ -│ • Event triggers │ -│ • Scheduled jobs │ -│ • Webhooks │ -│ │ -│ Security Layer │ -│ • Row-level security (RLS) │ -│ • Field-level encryption │ -│ • Data masking │ -│ • SCIM integration │ -│ • Compliance frameworks │ -│ │ -└────────────────────────────────────────────────────────────────────────┘ - - -┌────────────────────────────────────────────────────────────────────────┐ -│ Plugin Categories │ -├────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 💼 Core Business Plugins │ -│ • CRM (Customer Relationship Management) │ -│ • PM (Project Management) │ -│ • HRM (Human Resources) │ -│ • DMS (Document Management) │ -│ • SCM (Supply Chain) │ -│ │ -│ 🤖 AI-Enhanced Plugins │ -│ • AI Customer Support (Multi-channel chatbot) │ -│ • BI Analytics Suite (Predictive insights) │ -│ • NLQ (Natural Language Queries) │ -│ • Predictive Maintenance │ -│ • Marketing Automation │ -│ │ -│ 🏥 Industry-Specific Plugins │ -│ • Healthcare EMR (HIPAA-compliant) │ -│ • Financial Risk Management │ -│ • Manufacturing MES │ -│ • Retail POS │ -│ • Education LMS │ -│ │ -│ 🔌 Platform Enhancement Plugins │ -│ • Mobile App Builder │ -│ • API Gateway │ -│ • Flow Designer (Visual editor) │ -│ • Report Builder │ -│ • Integration Hub │ -│ │ -└────────────────────────────────────────────────────────────────────────┘ - - -┌────────────────────────────────────────────────────────────────────────┐ -│ Development Roadmap (2026) │ -├────────────────────────────────────────────────────────────────────────┤ -│ │ -│ Q1 │████████████████│ P0 Plugins │ -│ • CRM Foundation (4 weeks) │ -│ • Project Management (4 weeks) │ -│ • AI Customer Support (4 weeks) │ -│ │ -│ Q2 │████████████████│ P1 Plugins │ -│ • HRM (4 weeks) │ -│ • BI Analytics (4 weeks) │ -│ • Document Management (3 weeks) │ -│ • API Gateway (2 weeks) │ -│ │ -│ Q3 │████████████████│ P2 Plugins (Part 1) │ -│ • Healthcare EMR (8 weeks) │ -│ • Financial Risk (6 weeks) │ -│ │ -│ Q4 │████████████████│ P2 Plugins (Part 2) │ -│ • Manufacturing MES (6 weeks) │ -│ • Supply Chain (8 weeks) │ -│ │ -└────────────────────────────────────────────────────────────────────────┘ - - -┌────────────────────────────────────────────────────────────────────────┐ -│ Success Metrics & KPIs │ -├────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 📊 Technical Metrics │ -│ • Page Load Time: < 2s │ -│ • API Response: < 200ms (P95) │ -│ • Concurrent Users: 10,000+ │ -│ • System Uptime: 99.9% │ -│ • Test Coverage: > 80% │ -│ │ -│ 📈 Business Metrics (6 months) │ -│ • Active Plugins: 20+ │ -│ • Plugin Installs: 10,000+ │ -│ • Monthly Active Users: 5,000+ │ -│ • Paid Conversion: > 15% │ -│ │ -│ 🌐 Ecosystem Metrics │ -│ • 3rd Party Developers: 100+ │ -│ • ISV Partners: 20+ │ -│ • Open Source Contributors: 50+ │ -│ │ -│ 💰 Revenue Target (Year 1) │ -│ • Plugin Subscriptions: $2M │ -│ • Enterprise Licenses: $5M │ -│ • Professional Services: $3M │ -│ ───────────────────────────── │ -│ • Total ARR: $10M │ -│ │ -└────────────────────────────────────────────────────────────────────────┘ - - -┌────────────────────────────────────────────────────────────────────────┐ -│ Competitive Positioning │ -├────────────────────────────────────────────────────────────────────────┤ -│ │ -│ Feature ObjectStack Salesforce ServiceNow Odoo │ -│ ────────────────────────────────────────────────────────────── │ -│ Open Source ✅ ❌ ❌ ✅ │ -│ AI-Native ✅ 🟡 🟡 ❌ │ -│ Local-First ✅ ❌ ❌ ✅ │ -│ Metadata-Driven ✅ ✅ 🟡 ❌ │ -│ Extensible ✅ ✅ 🟡 🟡 │ -│ Price $ $$$$ $$$$ $$ │ -│ │ -│ 🎯 Differentiation Strategy │ -│ • Open-core model with enterprise features │ -│ • AI-native from ground up (13 AI protocols) │ -│ • Local-first, cloud-optional deployment │ -│ • Metadata-driven everything (137 protocols) │ -│ • Modern TypeScript stack with Zod validation │ -│ • Microkernel plugin architecture │ -│ │ -└────────────────────────────────────────────────────────────────────────┘ - - -═══════════════════════════════════════════════════════════════════════════ - For detailed specifications, see: - - �� Full Report (Chinese): PLUGIN_MARKETPLACE_DESIGN.md (31KB) - 📋 Executive Summary: PLUGIN_MARKETPLACE_SUMMARY.md (8.3KB) - 🗺️ Navigation Guide: PLUGIN_MARKETPLACE_README.md (4.1KB) - - Total Documentation: 1,503 lines across 3 comprehensive documents -═══════════════════════════════════════════════════════════════════════════ -``` - ---- - -**Last Updated**: February 6, 2026 -**Version**: 1.0 -**License**: MIT -**Copyright**: ObjectStack.ai 2026 diff --git a/docs/audits/README.md b/docs/audits/README.md index 3a0b6dbcc79..43f99ac26e8 100644 --- a/docs/audits/README.md +++ b/docs/audits/README.md @@ -1,5 +1,7 @@ # Metadata Property Liveness & Necessity Audit +> **Lifecycle of a file in `docs/audits/`:** an audit is *open* while its findings are being worked and *closed* once each one is fixed, ruled out or carried into a tracked ledger or issue; a closed audit moves to `docs/audits/archive/`, and git history keeps every version. + A protocol-level audit of **every ObjectStack metadata type**: for each schema property, cross-reference its spec definition against its **actual consumers** (`file:line`) in the runtime and renderers, to answer two questions in order — **(1) does the property take effect?** and **(2) is it necessary / reasonable?** Liveness is judged by **code consumption**, not browser observation (an unreactive UI can't distinguish "dead property" from "data didn't trigger it"). "DEAD" = parsed but read by no non-spec/non-test consumer → a **silent no-op** for authors. diff --git a/docs/launch-readiness.md b/docs/launch-readiness.md deleted file mode 100644 index cb09afea0f1..00000000000 --- a/docs/launch-readiness.md +++ /dev/null @@ -1,268 +0,0 @@ -# Launch Readiness Checklist - -**Status:** Draft for team sign-off -**Scope:** Production launch (v1 / GA) of the ObjectStack framework monorepo -**Last reviewed:** 2026-06-04 (`main` @ `9f311f8` — ADR-0030 P3b-2 digest) - ---- - -## How to use this document - -Each item has an **owner**, a **verification box**, and a **sign-off box**. The -two are deliberately separate: - -- ☐ **Verify** — a named engineer has confirmed the finding is real (or a false - positive) by reading the actual code / running a repro. Several items below - originate from an automated package-by-package sweep and are **not yet - hand-verified** — do not action them before verifying. -- ☐ **Sign-off** — the fix is merged (or the risk is formally accepted and the - acceptance recorded in the "Notes" column). - -A "false positive" still gets ticked on Verify, with a one-line note explaining -why no fix is needed. **Do not mark a P0 signed-off on the strength of the sweep -alone.** - -Priority key: **P0** = blocks launch · **P1** = fix at/just-after launch · -**P2** = test-coverage / hardening gap · **Roadmap** = explicitly out of v1. - ---- - -## Overall posture - -The codebase is mature and disciplined. A repo-wide scan found **zero** -`TODO/FIXME/HACK` markers, `console.log` in source, empty `catch` blocks, -`@ts-ignore`, or hard-coded secrets. `main` CI is green (Build/Test Core, Lint & -Type Check, CodeQL). The core tier — `spec`, `objectql`, `plugin-security`, -`runtime`, the SQL drivers, `service-ai` — is assessed production-ready. - -Launch risk is concentrated in a small number of themes below, not in code -quality. **The single most important caveat: the security- and data-integrity -findings (§P0) are from an automated sweep and MUST be hand-verified before any -fix or acceptance.** - ---- - -## P0 — Blockers (verify, then fix or formally accept) - -> Every P0 below must be **hand-verified** first — some may be false positives or -> already-guarded. Do not ship without each row at Verify ✓ **and** Sign-off ✓. - -### P0-1 — Auth secret falls back to a weak dev secret -- **Area:** `plugin-auth` — `src/auth-manager.ts` (~L1052–1071, `generateSecret()`) -- **Risk:** If `OS_AUTH_SECRET` is unset in production, the manager logs a warning - and falls back to `dev-secret-`. Session tokens become predictable → - session forgery. (HIGH, security) -- **Action:** Throw (fail boot) when no secret is configured and - `NODE_ENV === 'production'`; add a pre-boot config validation. Document - `OS_AUTH_SECRET` as a required go-live env var. -- **Owner:** _______ · Verify ✅ (confirmed real @ `main`) · Sign-off ☐ · Notes: Fixed — `generateSecret()` throws in production; +3 tests. Awaiting human sign-off. - -### P0-2 — Metadata-service failure bypasses all RBAC/RLS (fail-open) -- **Area:** `plugin-security` — `src/security-plugin.ts:309–312` -- **Risk:** A metadata-resolution error is swallowed and the request proceeds via - `next()` with **no permission checks**. If the metadata service degrades, every - user bypasses RBAC/RLS. (HIGH, security) -- **Action:** Add a circuit-breaker + ERROR-level alerting; add an integration - test asserting "metadata service down ⇒ request denied", not allowed. Decide - fail-closed vs. fail-open explicitly and record the decision. -- **Owner:** _______ · Verify ✅ (confirmed real @ `main`) · Sign-off ☐ · Notes: Decision = **fail-closed**. `catch` now logs ERROR + throws `PermissionDeniedError`; system ops still bypass. +2 tests. Awaiting human sign-off. - -### P0-3 — Unescaped LIKE metacharacters in `contains` -- **Area:** `driver-sql` — `src/sql-driver.ts:1565, 1656` -- **Risk:** The `contains` / `$contains` operator embeds the user value into a - `%...%` LIKE pattern without escaping `%` / `_`. Parameterization prevents SQL - injection, but a `%` value matches everything → logic-level filter bypass. - (HIGH, data) -- **Action:** Escape `%` and `_` (and the escape char) before building the LIKE - pattern; add a test with a `%`/`_` payload. -- **Owner:** _______ · Verify ✅ (confirmed real @ `main`) · Sign-off ☐ · Notes: Fixed — escape `%`/`_`/`\` + explicit `ESCAPE '\'` (SQLite needs it); +3 tests. Awaiting human sign-off. - -### P0-4 — MongoDB filter passes arbitrary `$` operators through -- **Area:** `driver-mongodb` — `src/mongodb-filter.ts:82–84` -- **Risk:** Operator keys are passed straight to MongoDB with no allowlist, so - `$where` / `$function` (server-side JS) reach the engine → query-intent bypass - and a potential JS-execution surface. (HIGH **if MongoDB is a launch driver**) -- **Action:** Allowlist safe operators (`$eq/$ne/$gt/$gte/$lt/$lte/$in/$nin/$and/$or/...`); - reject unknown ones at filter-build time. If MongoDB is not a v1 driver, mark - Roadmap instead. -- **Owner:** _______ · Verify ✅ (confirmed real @ `main`) · Sign-off ☐ · Notes: Fixed — translator now rejects unknown `$`-operators (blocks `$where`/`$function`); +4 tests. Awaiting human sign-off. (Still confirm whether MongoDB is a v1 driver.) - -### P0-5 — Realtime & feed are in-memory only (no cluster coordination) -- **Area:** `service-realtime` (`in-memory-realtime-adapter.ts`), `service-feed` - (`in-memory-feed-adapter.ts`) -- **Risk:** Publish/subscribe and feed storage are process-local. In a multi-node - deployment, clients connected to node B never receive node A's events, and feed - data is lost on restart / unbounded in memory. (HIGH **for HA/cluster**; - N/A for single-instance) -- **Action (cluster launch):** Provide a Redis-backed realtime adapter and a - DB-backed feed adapter, **or** formally restrict v1 to single-instance and - document it as non-HA. Enforce a `maxItems` cap if shipping in-memory feed. -- **Decision = single-instance for v1 (non-HA).** Recorded: realtime/feed stay - process-local for GA; HA is a post-GA fast-follow (the Redis primitive already - exists — `service-cluster-redis`'s `RedisPubSub` — so the realtime adapter is a - wrap, and a DB-backed feed adapter is the larger remaining piece). Both plugin - JSDocs now state the non-HA contract explicitly. -- **Backstops shipped:** safety caps are now **default-on** — `InMemoryFeedAdapter` - caps at `DEFAULT_MAX_FEED_ITEMS` (100k) and `InMemoryRealtimeAdapter` at - `DEFAULT_MAX_SUBSCRIPTIONS` (50k); `createFeedItem`/`subscribe` throw loudly at - the cap (fail-loud beats silent OOM). `0` is an explicit unbounded opt-out - (tests / short-lived processes). +4 tests (default-cap + opt-out, both packages). -- **Owner:** _______ · Verify ✅ (confirmed real @ `main`) · Sign-off ☐ · Notes: **Accepted for v1 as single-instance/non-HA**; caps default-on + documented. HA adapters tracked as post-GA roadmap. Awaiting human sign-off. - ---- - -## P1 — Fix at launch or immediately after - -### P1-1 — External calls have no timeout / retry / backoff -- **Area:** `embedder-openai` (`src/index.ts:~157`), `connector-rest` (~L157), - `connector-slack` (~L155), `connector-mcp` -- **Risk:** Naked `fetch` with no timeout or 429/5xx backoff → a slow or - rate-limited external API hangs the entire agent turn with no recovery. -- **Action:** Add a default request timeout (e.g. 30s, configurable) + exponential - backoff (3 tries) + a circuit breaker; tests for 429 / timeout paths. -- **Fix:** New shared `resilientFetch` (`@objectstack/spec/shared`) — 30s per-attempt - timeout (AbortController) + exponential backoff with jitter (3 tries) on - network errors / 429 / 5xx, honouring `Retry-After`; never retries a - caller-initiated abort. Wired into `connector-rest`, `connector-slack`, - `embedder-openai`. `connector-mcp` uses the MCP SDK transport, so it gets a 30s - per-request `timeout` on `callTool` / `listTools` instead. +13 tests (helper 9, - connector retry 1, plus existing suites green). -- **Deferred (follow-up, not blocking):** a **circuit breaker** — it's stateful - and per-host; timeout + backoff already removes the "hangs the agent turn / no - recovery" risk. Making timeout/retry **per-call configurable** (currently - sensible defaults) is a small follow-up. -- **Owner:** _______ · Verify ✅ (confirmed real @ `main`) · Sign-off ☐ · Notes: Timeout + backoff shipped across all 4 paths; circuit breaker deferred (rationale above). Awaiting human sign-off. - -### P1-2 — Unbounded growth: execution logs, job runs, event log -- **Area:** `service-automation` (in-memory exec logs, hard 1000 cap), - `service-job` (`sys_job_run`, no retention), `service-messaging` - (event log retention is opt-in) -- **Risk:** Long-running pods OOM; history tables grow without bound. -- **Action:** Make retention **default-on** for all event/run tables; schedule - sweepers at startup; persist automation logs to a table rather than memory. -- **Verification finding (corrected scope):** only one of the three is truly - unbounded. **automation** exec logs are *already* a bounded 1000-entry ring - buffer (`engine.ts` `recordLog` — `splice`); memory-safe today, never persisted - → no OOM risk. **`sys_job_run`** is the real leak: append-only, zero retention. - **messaging** retention was fully built + tested (`NotificationRetention`) but - shipped opt-in (`retentionDays: 0`). -- **Fixes shipped:** - - **service-job** — new `JobRunRetention` (mirrors `NotificationRetention`): - bulk `delete sys_job_run where created_at < cutoff` under a system context, - **default-on** at `DEFAULT_JOB_RUN_RETENTION_DAYS` (30d), swept every 6h via - an unref'd timer wired in `JobServicePlugin`'s `kernel:ready` (DB path only); - `retentionDays: 0` disables. +5 tests. - - **service-messaging** — flipped `retentionDays` default `0 → 90` - (`DEFAULT_NOTIFICATION_RETENTION_DAYS`); sweeper/timer/shutdown already - existed. **Behaviour change**: notification history now auto-prunes at 90d by - default (set `0` to keep the old keep-forever behaviour). Changeset notes it. - - **service-automation** — exec-log ring buffer cap made configurable via - `AutomationServicePluginOptions.maxLogSize` (default unchanged at 1000, - `DEFAULT_MAX_EXECUTION_LOG_SIZE`); +2 tests. Durable `sys_automation_run`-style - persistence is deferred to the HA fast-follow (roadmap), not a GA blocker. -- **Superseded (ADR-0057, #2786/#2834):** the plugin-local sweepers above were - the stop-gap. Retention is now a *declarative platform primitive*: objects - carry a `lifecycle` block (`sys_job_run` 30d, notification pipeline 90d) and - the ObjectQL-registered **LifecycleService** is the ONE sweeper — - `JobRunRetention` / `NotificationRetention` and their `retentionDays` - options were removed. Windows are tuned via the `lifecycle` settings - namespace (`retention_overrides`, tenant-scoped). `sys_automation_run` - deliberately keeps its OWN terminal-only sweep (suspended runs are live - resumable state; the declarative contract has no status predicate). -- **Owner:** _______ · Verify ✅ (confirmed real @ `main`; scope corrected) · Sign-off ☐ · Notes: `sys_job_run` retention is the one true fix; messaging default-flipped; automation already bounded (now tunable). Awaiting human sign-off. - -### P1-3 — Graceful shutdown (mostly a false positive; one real drain bug fixed) -- **Area:** `core` (`kernel.ts`), `cli` (`serve.ts`), `plugin-hono-server` (`adapter.ts`) -- **Verification finding:** The sweep's "no SIGTERM/SIGINT handling" is **wrong**. - `Kernel.registerShutdownSignals()` (called at start) already handles - SIGINT/SIGTERM/SIGQUIT → `shutdown()` → `performShutdown()` (ordered plugin - destroy in reverse + `kernel:shutdown` hook + `onShutdown` handlers), bounded by - a **default 60s** `shutdownTimeout`. `serve.ts` boots through the kernel, so the - production path inherits all of this. The ≥60s grace floor already exists. -- **Real (narrower) gap — FIXED:** the standalone Hono server's `close()` called - `closeAllConnections()`, which **force-killed in-flight requests** instead of - draining them. Replaced with: `server.close()` (stop new + drain active) + - `closeIdleConnections()` (release idle keep-alive), and force-close only after a - bounded **drain window** (default 10s, < the kernel's 60s). +2 integration tests. -- **Residual (not blocking):** the Hono adapter - intentionally leave signal handling to the host app; cluster/Redis close should - be registered via `kernel.onShutdown(...)` by the cluster plugin — confirm it is. -- **Owner:** _______ · Verify ✅ (mostly false positive; drain bug fixed) · Sign-off ☐ · Notes: Kernel shutdown already correct; hono drain fixed + tested. Awaiting human sign-off. - -### P1-4 — Per-request hostname → environment resolution (no cache) -- **Area:** `rest` — `src/rest-server.ts:~504–530` -- **Risk:** `resolveByHostname()` runs on every unscoped request → control-plane - latency spike under load; silent fallback to default project masks it. -- **Action:** Add an in-memory TTL cache (~30s) for `hostname → environmentId`. -- **Owner:** _______ · Verify ✅ (confirmed real @ `main`) · Sign-off ☐ · Notes: Fixed — `RestServer.resolveHostnameCached()` caches hostname→env (positive **and** negative) for 30s across all 3 call sites; +3 tests. Awaiting human sign-off. - -### P1-5 — Cluster pub/sub is fire-and-forget (metadata-changed) -- **Area:** `service-cluster-redis` — `src/pubsub.ts:~75–90` -- **Risk:** `publish()` doesn't wait for subscribers; a crash right after a schema - change leaves other nodes with a stale schema until the next full reload. -- **Action:** Acceptable for non-critical events if documented; ensure schema - mutations re-sync on error boundaries (history exists in `sys_metadata_history`). - Record the durability contract. -- **Durability contract (recorded):** Redis pub/sub is **at-most-once** by design - (already noted in `pubsub.ts`). `metadata.changed` is a **cache-invalidation hint - only** — the durable source of truth is the transactional write to `sys_metadata` - (+ `sys_metadata_history`). A node that misses the event serves its cached schema - until the next reload and **loses no data** (self-heals on reload/restart against - the DB). Documented in `pubsub.ts publish()`. **Accept** for v1: no exactly-once - state may flow through this channel — durable state uses an outbox. -- **Owner:** _______ · Verify ✅ (by design — contract recorded) · Sign-off ☐ · Notes: No code fix needed; risk **accepted** with rationale + code comment. Awaiting human sign-off. - ---- - -## P2 — Test-coverage & hardening gaps (ready, but shore up) - -| ID | Area | Gap | Action | Owner | Verify | Sign-off | -|----|------|-----|--------|-------|:------:|:--------:| -| P2-1 | `metadata-fs` | **NEEDS-WORK.** Atomicity / `watch` replay consistency under concurrent FS writes; 200ms chokidar self-write suppression is racy on slow/network FS | Add fault-injection tests (crash mid-write, concurrent put+delete, watch replay); validate `writeJsonAtomic` | ____ | ☐ | ☐ | -| P2-2 | `cli` | Missing `serve` integration test (kernel init + HMR reload + SIGINT); possible missing `environments.ts` implementation (test exists) | Add serve/dev integration test; confirm `environments` command exists | ____ | ☐ | ☐ | -| P2-3 | `plugin-webhooks` | Thin tests (1 test file); `eventId` dedup can collide on identical-ms timestamps | Add UUID suffix to `eventId`; expand auto-enqueuer tests | ____ | ☐ | ☐ | -| P2-4 | `service-queue` | CAS claim (read-then-update) is not atomic → tolerated duplicate delivery; empty idempotency key bypasses dedup | Enforce non-empty idempotency key; add a lease safety margin; document at-least-once | ____ | ☐ | ☐ | -| P2-5 | `plugin-audit` | `sys_session` mutations are not audited | Confirm login/logout are logged elsewhere (`sys_audit_log`); close the compliance gap if not | ____ | ☐ | ☐ | -| P2-6 | `core` / `runtime` | `getService()` is sync but may return a Promise → unhandled-rejection footgun for plugin authors | Tighten the type / add a guard; document the sync-only contract | ____ | ☐ | ☐ | - ---- - -## Roadmap — Explicitly out of scope for v1 (no action to launch) - -These are **designed but unbuilt** and should be named "not in v1" in the release -notes, not treated as blockers. - -- ☐ **Unverified features — confirm stub vs. minimal, then include or exclude:** - `knowledge-ragflow`, `connector-openapi` (the sweep could not locate full - implementations; the packages exist — verify scope before GA). -- ☐ **HA / multi-node (post-GA fast-follow, from P0-5 decision):** Redis-backed - realtime adapter (wrap `service-cluster-redis`'s `RedisPubSub`), DB-backed feed - adapter, and persisting automation execution logs to a table (currently a - process-local 1000-entry ring buffer — see P1-2). Not needed for single-instance v1. -- ☐ **Proposed ADRs (roadmap):** ADR-0021 (analytics semantic layer), - ADR-0022/0023/0024 (connectors / OpenAPI→connector / MCP connectors), - ADR-0025/0026 (plugin & client-UI distribution), ADR-0027 (metadata authoring - lifecycle), ADR-0028 (naming/namespace isolation), ADR-0029 (kernel object - ownership — **partially landed**: K0 + D7 + several K2 domains), ADR-0033 - Phase D (enterprise AI-authoring governance). - ---- - -## Release mechanics - -- ☐ `main` CI green at the release commit (Build/Test Core, Lint & Type Check, CodeQL). -- ☐ Pending changesets reviewed (4 at last check) and version bump intentional. -- ☐ `pnpm run release` path verified (`build` → `build-console.sh` → `changeset publish`). -- ☐ Required env vars documented for go-live (at minimum `OS_AUTH_SECRET`; see P0-1). -- ☑ Deployment topology decided: **single-instance** for v1 (drives P0-5; HA is a - post-GA fast-follow). Realtime/feed run process-local with default-on memory caps. - ---- - -## Provenance - -The per-package findings were produced by an automated, read-only package-by-package -sweep on 2026-06-04 and synthesized here. They are a **starting point for review, -not a verified defect list** — each item carries its own Verify box for exactly -this reason. File:line references are approximate and must be confirmed against -`main` before acting. diff --git a/docs/plans/m1-project-artifact-schema.md b/docs/plans/m1-project-artifact-schema.md deleted file mode 100644 index 166c013a44e..00000000000 --- a/docs/plans/m1-project-artifact-schema.md +++ /dev/null @@ -1,136 +0,0 @@ -# Plan: M1 — Artifact Envelope Schema (packages/spec) - -> **v5.0 update (2026):** Throughout this document, the term *project* has been renamed to *environment* (no aliases; CLI flags, URL paths, schemas, env vars all hard-renamed). See ADR-0006 for the rationale and `.changeset/v5-project-to-environment-rename.md` for the breaking-change list. The body below is preserved verbatim for historical context. - - -## Context - -ROADMAP M1 is the prerequisite for everything downstream (M2–M5, D1, D3). -The goal is a Zod schema for the **project build artifact envelope** — the JSON blob -that `objectstack compile` writes to `dist/objectstack.json` and `objectstack publish` -uploads to `POST /api/v1/cloud/projects/:projectId/metadata`. - -The existing `package-artifact.zod.ts` describes a **plugin marketplace .tgz** (file -listings, digital signatures, etc.). M1 is a different concept: a **project metadata -snapshot** produced by the CLI and consumed by the control plane + ObjectOS. - -### Schema scope (narrow on purpose) - -`ProjectArtifactSchema` describes **only the `GET /api/v1/cloud/projects/:projectId/artifact` -response shape** — the assembled artifact ObjectOS pulls from the control plane. - -It is explicitly NOT: -- the CLI compile output (`dist/objectstack.json` stays a raw `ObjectStackDefinitionSchema`); -- the POST publish request body (the CLI uploads `ObjectStackDefinitionSchema` directly); -- the POST publish response shape (`PublishResponseSchema` is deferred to M5). - -Narrowing to a single use case lets every envelope field stay required, instead of -forcing half of them optional to accommodate multiple lifecycle stages. - ---- - -## Design Decisions - -| Decision | Rationale | -|:---|:---| -| No root re-export in `packages/spec/src/index.ts` | Root only exports key utilities; consumers use subpath `@objectstack/spec/cloud` | -| New `Sha256DigestSchema` instead of reusing `ArtifactChecksumSchema` | `ArtifactChecksumSchema` is a file-list checksum map for marketplace .tgz; M1 needs a single artifact digest | -| No top-level `functions` field | Functions/hooks are part of `ObjectStackDefinitionSchema` (stack application definition); not envelope concerns | -| No top-level `manifest` field | Naming is ambiguous with `metadata.manifest` (app's `ManifestSchema`); runtime requirements shape is undefined in Phase 1 — omit entirely | -| `schemaVersion: '0.1'` | Pre-stable version; signals breaking changes are expected | -| `commitId` required (not optional) | Assigned by control plane; CLI receives it in the publish response | -| `checksum` covers only the `metadata` block | `sha256(canonicalJSON(metadata))` using stable key ordering (e.g. `fast-json-stable-stringify`). Envelope-level fields (`commitId`, `builtAt`, …) are excluded so the digest stays stable across re-assembly | -| `PublishResponseSchema` deferred to M5 | M1 only defines the GET response envelope; POST response shape is M5's concern | - ---- - -## New File - -**`packages/spec/src/cloud/project-artifact.zod.ts`** - -```ts -import { z } from 'zod'; -import { lazySchema } from '../shared/lazy-schema'; -import { ObjectStackDefinitionSchema } from '../stack.zod'; - -// --- SHA-256 digest of a single artifact payload --- -export const Sha256DigestSchema = z - .string() - .regex(/^[a-f0-9]{64}$/, 'Must be a 64-character lowercase hex SHA-256 digest') - .describe('SHA-256 digest (64 hex chars)'); - -export type Sha256Digest = z.infer; - -// --- Artifact envelope --- -export const ProjectArtifactSchema = lazySchema(() => z.object({ - /** Envelope format version. Increment on breaking changes. */ - schemaVersion: z.literal('0.1').default('0.1'), - - /** Control-plane project ID this artifact belongs to. */ - projectId: z.string(), - - /** Metadata revision assigned by the control plane on publish. */ - commitId: z.string(), - - /** SHA-256 digest of the canonical JSON serialization of the `metadata` block (stable key ordering). Computed by the control plane when assembling the GET response. */ - checksum: Sha256DigestSchema, - - /** Build timestamp (ISO 8601). */ - builtAt: z.string().datetime().optional(), - - /** CLI version that produced this artifact (e.g. "objectstack-cli@0.4.0"). */ - builtWith: z.string().optional(), - - /** - * Full compiled metadata definition. - * Includes objects, views, flows, hooks, functions, agents, etc. - * This is the direct output of `objectstack compile`. - */ - metadata: ObjectStackDefinitionSchema, -})); - -export type ProjectArtifact = z.infer; -export type ProjectArtifactInput = z.input; -``` - ---- - -## Export wiring - -**`packages/spec/src/cloud/index.ts`** — add named export: -```ts -export * from './project-artifact.zod'; -``` - -No root re-export. Consumers import via subpath: -```ts -import { ProjectArtifactSchema, Sha256DigestSchema } from '@objectstack/spec/cloud'; -``` - ---- - -## Critical files - -| File | Action | -|:---|:---| -| `packages/spec/src/cloud/project-artifact.zod.ts` | **Create** | -| `packages/spec/src/cloud/index.ts` | Add export | -| `packages/spec/src/stack.zod.ts` | Read-only (import `ObjectStackDefinitionSchema`) | -| `packages/spec/src/kernel/package-artifact.zod.ts` | Read-only reference only — do NOT import from it | - ---- - -## Verification - -1. `pnpm build` — `packages/spec` builds clean. -2. `pnpm test` — no regressions. -3. Smoke: `import { ProjectArtifactSchema } from '@objectstack/spec/cloud'` resolves correctly. -4. Parse a minimal valid payload: - ```ts - ProjectArtifactSchema.parse({ - projectId: 'proj_123', - commitId: 'abc', - checksum: 'a'.repeat(64), - metadata: { /* minimal ObjectStackDefinition */ }, - }); - ``` diff --git a/docs/plans/release-15.1-test-plan.md b/docs/plans/release-15.1-test-plan.md deleted file mode 100644 index cb98cced3cc..00000000000 --- a/docs/plans/release-15.1-test-plan.md +++ /dev/null @@ -1,112 +0,0 @@ -# 15.1 发布测试清单 - -> 范围:framework `@objectstack/*@15.0.0 → 15.1.0`(87 commits, 65 changesets)+ -> 配套 Console `objectui 14.0.0 → 14.1.0`(94 commits,framework 钉在 `b8967495be73`)。 -> 环境:`examples/app-showcase` + `objectstack dev --ui --seed-admin`(独立端口 + 独立 file DB)。 -> 标注:🖥 = 浏览器验证;🔌 = API/CLI 验证;🤖 = 已有自动化钉死(dogfood/e2e 测试,CI 覆盖)。 - -## A. 安全加固(本次最大主题) - -| # | 项 | 方式 | 验证要点 | 来源 | -|---|---|---|---|---| -| A1 | 静态 `readonly` UPDATE 强制 | 🔌🤖 | REST PATCH 一个 `readonly: true` 字段 → 该字段被 strip,响应中值不变;`isSystem` 写不受影响 | #2948/#2957/#3003,`showcase-static-readonly.dogfood.test.ts` | -| A2 | `readonlyWhen` 多行 UPDATE 强制 | 🔌🤖 | bulk update 命中任一锁定行 → 字段对整批丢弃 | #3042 | -| A3 | `owner_id` 锚点:insert 伪造/update 转移拒绝、批量 stamp | 🔌🤖 | 非特权用户 insert 他人 owner_id → 拒;bulk insert 空 owner → stamp 为当前用户 | #3004/#3018,`owner-anchor-and-bulk-writes.dogfood.test.ts` | -| A4 | bulk write 按 owner/RLS write filter 收窄 | 🔌🤖 | member 对 OWD-private 对象 `update({multi:true})` → 只命中自己行 | #2982 | -| A5 | 引擎级联豁免(删用户 set_null 不被 A3 拦) | 🔌🤖 | 删除 sys_user → 其拥有记录 owner_id 被正常清空,级联不中断 | #3023/#3048 | -| A6 | `$expand` 强制被引对象 RLS/FLS | 🔌🤖 | 以受限用户 `?expand=` 引用 → RLS 隐藏行不返回、FLS 字段掩码 | #2850/#2961 | -| A7 | public form 剥离 server-managed 锚点 | 🖥🔌 | 公开表单渲染不出现 owner_id/organization_id 等;POST 携带被剥离 | #3022/#3036 | -| A8 | 匿名 deny 全 HTTP 面统一 | 🔌🤖 | 未登录 `POST /graphql`、raw `/data` → 401(`requireAuth` 默认) | #2567 系列,`showcase-anonymous-deny-surfaces.dogfood.test.ts` | -| A9 | MCP `run_action` 需 `ai.exposed`,fail-closed | 🔌 | 未声明 action 经 MCP 调用被拒;声明后可调且入 audit log | #2964 | -| A10 | reports IDOR / 定时报表 RLS / RAG fall-open | 🔌🤖 | 跨 owner 按 id 读/删 saved report → 拒 | #2980/#2981/#2975 | -| A11 | OWD 保存门:packaged 对象只能收紧 sharingModel;`external ≤ internal` | 🖥 | Studio 里把 packaged 对象 OWD 往宽改 → 保存被拒;OWD 总览 inline 校验 | #3050 + objectui#2508 | -| A12 | 附件访问链(读继承 parent、下载 401/403+签名 URL、attach 需 parent EDIT) | 🖥🔌🤖 | 见 C 组;非授权下载 → 401/403 | #2755/#2970 | -| A13 | sharing rule seed-not-clobber + capability scope seed-once | 🔌 | 管理员改动不被重启 seed 覆盖 | #2909 | -| A14 | better-auth 1.7.0-rc.1(GHSA 修复)登录链路 | 🖥 | 登录成功且后续请求 200(sys_jwks alg/crv 列) | #2974 | - -## B. 声明式 Connector(ADR-0096/0097) - -| # | 项 | 方式 | 验证要点 | 来源 | -|---|---|---|---|---| -| B1 | provider-bound 实例 boot materialization | 🔌🤖 | showcase live `provider:'mcp'` demo:boot 后 `GET /api/v1/automation/connectors` 有该实例,`origin:'declarative'` | #2994/#3062 | -| B2 | flow designer connector picker 标注声明式实例 | 🖥 | connector_action 节点下拉列出实例并带标注 | objectui#2563 | -| B3 | 上游不可达 → degraded husk + 退避重试,恢复原子换入 | 🔌 | 断掉 upstream 重启 → boot 不挂,descriptor `state:'degraded'` | #3049 | -| B4 | declarative stdio 默认拒绝,host allowlist opt-in | 🔌 | 未 opt-in 的 stdio 实例 → boot fatal/reload skip | #3059 | -| B5 | openapi spec 文件路径(package 相对,拒绝逃逸) | 🔌 | `providerConfig.spec: './openapi.json'` 可解析;`../` 拒 | #3024 | -| B6 | descriptor-only 契约 boot 审计 | 🔌 | actions 无运行时注册 → boot warning;`enabled:false` 静音 | #2985 | - -## C. 附件 v1 - -| # | 项 | 方式 | 验证要点 | 来源 | -|---|---|---|---|---| -| C1 | 记录详情 RecordAttachmentsPanel 认证上传/下载 | 🖥 | 上传成功;下载经签名 URL;无权限时友好拒绝文案 | objectui#2532 | -| C2 | 发票行 per-line Receipt(inline grid 内上传单元格) | 🖥 | showcase Invoice → 行内 Receipt 列出现上传控件 + chips/缩略图,非文本框 | #3051 + objectui#2585 | -| C3 | 附件读继承 parent 可见性 | 🔌🤖 | 受限用户列附件 → 不可见 parent 的行与计数均不出现 | #2970 | -| C4 | sys_file 孤儿 tombstone/reap + upload_session 报废(abort multipart) | 🔌🤖 | 生命周期测试覆盖 | #2755/#2970 | - -## D. Dashboard 全局筛选 - -| # | 项 | 方式 | 验证要点 | 来源 | -|---|---|---|---|---| -| D1 | Revenue Pulse:filter bar 驱动多图表 | 🖥 | 切 filter/日期预设 → 多 widget 同步 re-scope;opt-out widget 不动;dirty 出 Reset | #3038/#2576 | -| D2 | widget inspector 可视化 filterBindings 编辑 | 🖥 | Studio 选中 widget → "Dashboard filter bindings" 区,开关 Apply/换字段 | objectui#2586 | -| D3 | spec-form filter options 不再崩 dashboard;select 显示 label | 🖥 | 有 `{value,label}` options 的 dashboard 正常渲染 | objectui#2597 | - -## E. Console 核心体验(objectui 14.1) - -| # | 项 | 方式 | 验证要点 | 来源 | -|---|---|---|---|---| -| E1 | Record 级 inline edit:共享 draft + 单次原子 Save | 🖥 | 双击正文字段 + highlight 各改一处 → 同一 Save 条;Network 仅一次 update(只含改动 key + ifMatch);Esc/Cmd+Enter | objectui#2542/#2549/#2604 | -| E2 | 多按钮 record header(order + primary tie-break,⋯ 溢出) | 🖥 | ≥3 动作对象详情页头并排按钮;Delete/Share 进 ⋯ | objectui#2574 | -| E3 | related list 权限门控 | 🖥 | 对子对象无 read 权限用户 → section 整体不渲染 | objectui#2565 | -| E4 | kanban:stageField 默认 lane + highlightFields 默认卡片 | 🖥 | 未配 lane/cardFields 的看板按语义角色渲染 | objectui#2596/#2541 | -| E5 | 拼音搜索:列表快搜/lookup picker/⌘K 输 `zw` 命中中文 | 🖥 | showcase 种子开箱可演示 | #3027/#3034 | -| E6 | conditional tabs(page:tabs item visibleWhen) | 🖥 | 谓词为 FALSE 时整个 tab 消失,变量变化 live 重估 | #2967 + objectui#2516 | -| E7 | B3 级联选项:client re-filter + server 拒绝 | 🖥🤖 | cascading-select fixture;live e2e 已钉 | #3006 + objectui#2547/#2562 | -| E8 | GB18030 CSV 导入 | 🖥 | 导入 GBK 编码 CSV → 中文表头正常、可映射 | objectui#2557 | -| E9 | toast 不再因 error 对象崩页(React #31) | 🖥 | 触发 400 的操作 → 可读 toast,页面不白屏 | objectui#2580 | -| E10 | Studio/metadata-admin 跟随应用 locale | 🖥 | 切 en/zh → Studio 同步切换,无混语言 | objectui#2602 | -| E11 | 活动 feed/audit 摘要 workspace locale 本地化 | 🖥 | zh 环境下动词模板 + 对象 label 中文 | #3045/#3029 | -| E12 | Create User:param 可翻译 + 显式密码胜出 | 🖥 | zh 下对话框字段中文;输显式密码不报 400 | #3030/#3031/#3033 | -| E13 | action visible 三陷阱(os.user.* 别名/record_more/报错谓词 warn) | 🖥🤖 | `locations:['record_more']` 动作出现在 ⋯ 菜单 | objectui#2611 | - -## F. Studio(设计期) - -| # | 项 | 方式 | 验证要点 | 来源 | -|---|---|---|---|---| -| F1 | CEL formula 编辑器:推断结果类型、summary 结构化 roll-up | 🖥 | `record.amount * 1.1` → Result type: Number;裸字段名报错给修法 | objectui#2609 | -| F2 | 字段条件规则 CEL 编辑器(visibleWhen/readonlyWhen/requiredWhen) | 🖥 | `previous.` 成员补全 + did-you-mean | objectui#2571 | -| F3 | list-view 条件格式化编辑器(first-match-wins) | 🖥 | 加 CEL+颜色规则 → 运行时行着色 | objectui#2558/#2544 | -| F4 | RLS 编辑器 lint/补全/test-run | 🖥 | 每策略选记录试跑命中 | objectui#2533 | -| F5 | Access:OWD 总览批量编辑 + 深链 + external≤internal 校验 | 🖥 | 见 A11 | objectui#2508 | -| F6 | Access:unsaved 三连守卫(矩阵/pillar SPA 导航/OWD 行) | 🖥 | 不保存点走 → confirm;取消保留编辑 | objectui#2588/#2606/#2610 | -| F7 | 只读包锁定权限矩阵 | 🖥 | read-only 包矩阵置灰、无 Save | objectui#2570 | -| F8 | AccessExplainPanel record 粒度 + 三态溯源徽标 | 🖥 | 选记录 → visible 结论横幅 + 逐层归因 | objectui#2502/#2501 | -| F9 | flow palette 搜索/键盘导航/云同步 recents | 🖥 | 搜索框 + ↑↓ Enter;recents 分组 | objectui#2543/#2553 | -| F10 | Decision Branches 行内 Target 选择 | 🖥 | 表内选目标 → 画布连边;清除只断边 | objectui#2568 | -| F11 | Page/View inspector 不崩(lazySchema × toJSONSchema) | 🖥 | Studio 打开 Page/View 编辑面 → 无 `setting 'ref'` 崩溃 | #3021 | -| F12 | package spec-form modal + namespace 前缀编辑期强制 | 🖥 | New package modal;"+ new object" 自动 `_` 前缀 | objectui#2535/#2524 | -| F13 | feature-gated action UI 门控 | 🖥 | 关插件 → 相关按钮消失而非 404 | #2965 + objectui#2536 | - -## G. 平台 / 协议 / 部署(API·CLI 面) - -| # | 项 | 方式 | 验证要点 | 来源 | -|---|---|---|---|---| -| G1 | `aggregate_records` MCP 工具走 ENGINE 读路径 | 🔌 | RLS/tenant 与 find 一致;FLS 输入门 fail-closed | #2976 | -| G2 | standalone authored action 上 MCP 桥 | 🔌 | Studio 授权独立 action `ai.exposed:true` → list_actions 可见 | #3010/#3020 | -| G3 | packages REST:PATCH 路由/POST 重复 409/install overwrite | 🔌 | 三条包管理修复 | #2995/#2971/#3007 | -| G4 | ADR-0087:durable-package rehydration 握手 + `migrate meta --from 10` | 🔌 | 不兼容包结构化拒载,boot 继续 | #2972 | -| G5 | honest capabilities:discovery 不虚报 realtime/stub 状态 | 🔌 | discovery JSON 无 `/realtime` 虚假路由 | ADR-0076 slice | -| G6 | `kernel:bootstrapped` + `app:seeded` membership backfill | 🔌 | seed 完成后无需重启即有 membership | #2989/#3000 | -| G7 | Docker 镜像 + 脚手架 container-ready | 🔌 | `docker run` + `/api/v1/health` 200 | #2952/#2979 | -| G8 | tenancy strict block:未知 key 响亮 parse error + tombstone | 🔌 | `strategy:` 残留 → 报错含迁移指引 | #2962 | -| G9 | 拼音 `__search` 伴随列 boot backfill + reconcile | 🔌 | 存量行重启后可拼音搜到 | #3027 | -| G10 | REST 403 透传 / 未知 `$` 参数 400 | 🔌 | 记录级 403 带 code;`$bogus=1` → 400 UNSUPPORTED_QUERY_PARAM | #2926 ⑦⑩ | - -## 回归门(发布前必须全绿) - -- [ ] `pnpm build` 全绿(71 包) -- [ ] `pnpm test` 全绿(含 dogfood 套件:owner-anchor / static-readonly / anonymous-deny / attachments matrix / detail-shapes e2e / MCP connector CI-pinned demo) -- [ ] objectui `e2e/live/showcase-smoke.spec.ts`(全 showcase surface 白屏/空图表/占位符泄漏扫描) -- [ ] `pnpm check:release-notes`(release 页 drift guard) -- [ ] `os validate` 对 examples(schema+表达式+widget 三道门) diff --git a/docs/qa/platform-checklist/README.md b/docs/qa/platform-checklist/README.md index 8541599963f..440ac972b0e 100644 --- a/docs/qa/platform-checklist/README.md +++ b/docs/qa/platform-checklist/README.md @@ -3,7 +3,7 @@ A durable, machine-readable checklist of platform capabilities that an **AI agent executes** against a running app (browser + API + CLI + build gates). It replaces the one-off shapes release verification used before — a hand-written table per release -([docs/plans/release-15.1-test-plan.md](../../plans/release-15.1-test-plan.md)) and a +([docs/plans/release-15.1-test-plan.md](https://github.com/objectstack-ai/objectstack/blob/df8aac41f2d9d14db04afdfe48511216419dafc0/docs/plans/release-15.1-test-plan.md)) and a checkbox issue per release (#3358) — with one ledger that **accumulates across releases**, supports append/change without losing history, and pins every tick to an acceptance oracle and captured evidence. @@ -483,7 +483,7 @@ ledger** as revisions — that is the accumulation the one-off checklists never | `packages/qa/dogfood` golden tests | Permanent pins for historical regressions — the `automated.ref` target for API-lane items. | | `examples/app-showcase/src/coverage.ts` | The ratchet that every spec variant is *demonstrable*. This ledger asserts the demonstrations *work when driven*. Fixture gaps found here should often be fixed there. | | objectui `e2e/live/*` + ADR-0054 | The browser-lane automation and the UI-testability contract (stable locators, machine-readable async state) that makes browser oracles trustworthy. | -| `docs/plans/release-15.1-test-plan.md`, #3358 | The predecessors this generalizes. Their vocabulary (方式 lanes, 验证要点, 来源) maps to `surface`, `acceptance`, `source`. | +| `docs/plans/release-15.1-test-plan.md` (deleted; read it at commit `df8aac41`), #3358 | The predecessors this generalizes. Their vocabulary (方式 lanes, 验证要点, 来源) maps to `surface`, `acceptance`, `source`. Item `source` rows that cite its sections (`§A13`, …) resolve at that commit. | **Deliberately not reused:** `packages/spec/src/qa/testing.zod.ts` (`TestScenarioSchema`). Its action vocabulary is headless-API-only diff --git a/docs/upgrading-to-11.md b/docs/upgrading-to-11.md deleted file mode 100644 index 42359d7c9b4..00000000000 --- a/docs/upgrading-to-11.md +++ /dev/null @@ -1,154 +0,0 @@ -# Upgrading to ObjectStack 11 - -ObjectStack 11 is a focused breaking release: it sharpens the **open edition** down -to what is actually shipped and dogfooded, and removes a batch of long-deprecated -APIs. This guide lists every breaking change from **10.x → 11.x** with a concrete -migration for each. - -> The breaking changes are spread across the 11 line (11.0.0 + 11.1.0). There is -> one migration target: **the latest 11.x**. Pin `@objectstack/*` to `^11`. - -## Quick checklist - -- [ ] AI authoring service is no longer bundled in the open edition → see [MCP-only](#open-edition-is-mcp-only). -- [ ] Using a non-Hono HTTP adapter (Express/Fastify/Next/Nest/Nuxt/SvelteKit) or `@objectstack/plugin-msw`? → [Adapters](#http-adapters-hono-only). -- [ ] Flow nodes typed `http_request` / `http_call` / `webhook` → rename to `http`. -- [ ] `@objectstack/client-react` `useQuery` using `select`/`filters`/`sort`/`top`/`skip` → canonical names. -- [ ] Code referencing `IUIService` → `IMetadataService`. -- [ ] Driver code typed `DriverInterface` (the alias) → `IDataDriver`. -- [ ] `.env` using `OS_MULTI_TENANT` / `OBJECTSTACK_METADATA_WRITABLE` / `AUTH_BASE_URL` → rename. -- [ ] Stack `policies` / `definePolicy` → removed (was never enforced). - ---- - -## Open edition is MCP-only - -The bundled AI authoring service (`@objectstack/service-ai`) is **no longer part of -the open distribution** (ADR-0025). AI integrates through MCP (`@objectstack/mcp`) -plus the documented opt-in seam. - -**Migration** -- If you don't use AI authoring: nothing to do. -- If you do: declare `@objectstack/service-ai` / `@objectstack/service-ai-studio` - as an app dependency (the CLI auto-registers the service only when the host app - declares it), or run on the commercial distribution. MCP tooling is unaffected. - -## HTTP adapters: Hono only - -The open edition now ships **only the Hono adapter** (`@objectstack/hono`). These -packages were removed (zero internal consumers, not dogfooded): -`@objectstack/express`, `@objectstack/fastify`, `@objectstack/nextjs`, -`@objectstack/nestjs`, `@objectstack/nuxt`, `@objectstack/sveltekit`, and -`@objectstack/plugin-msw`. - -**Migration** -- **On Hono already** → no change. -- **On another framework** → either move to Hono (`createHonoApp` / `objectStackMiddleware`, - runs on Node/Bun/Deno/Workers), or build a thin adapter on the public - `HttpDispatcher` API / `createDispatcherPlugin` (the removed adapters were ~50-line - wrappers; you can vendor one out-of-tree). -- **Used `@objectstack/plugin-msw`** for test mocking → use `msw` directly, or - drive the kernel via `@objectstack/hono` in tests. - -```ts -// before: import { objectStackPlugin } from '@objectstack/fastify'; -import { createHonoApp } from '@objectstack/hono'; -const app = createHonoApp({ kernel, prefix: '/api/v1' }); -``` - -## Flow node type: `http` - -The deprecated flow-node aliases `http_request` / `http_call` / `webhook` are -removed; the canonical type is **`http`** (same behavior — durable outbox when -`config.durable`, inline fetch otherwise). Authoring a removed type now fails fast -at parse instead of silently resolving. - -```ts -// before: { id: 'call', type: 'http_request', config: { url, method } } -{ id: 'call', type: 'http', config: { url, method } } -``` - -> The trigger `eventType: 'webhook'` and the `webhook` resume event are unchanged — -> only the HTTP **node** aliases were removed. - -## `@objectstack/client-react`: canonical query fields - -`useQuery` / `useInfiniteQuery` no longer accept the legacy aliases: - -| removed | use | -|---|---| -| `select` | `fields` | -| `filters` | `where` | -| `sort` | `orderBy` | -| `top` | `limit` | -| `skip` | `offset` | - -```ts -// before: useQuery('account', { select: ['name'], filters, sort, top: 20, skip: 40 }) -useQuery('account', { fields: ['name'], where, orderBy, limit: 20, offset: 40 }); -``` - -## `IUIService` → `IMetadataService` - -The deprecated `IUIService` contract is removed. Views and dashboards are metadata: - -```ts -// before: ui.getView(name) / ui.registerView(name, def) -metadata.get('view', name); -metadata.register('view', name, def); -``` - -## `DriverInterface` (alias) → `IDataDriver` - -The deprecated `DriverInterface` type alias (`= IDataDriver`) is removed. Use -`IDataDriver` — the shape is identical. - -```ts -// before: import { DriverInterface } from '@objectstack/runtime'; -import type { IDataDriver } from '@objectstack/spec/contracts'; -``` - -> Unrelated and unchanged: the live `IDataEngine` (engine-layer contract) and the -> zod-derived `DriverInterface` / `DriverInterfaceSchema` in `@objectstack/spec/data`. - -## Environment variables: ObjectStack's own renames removed - -The framework's **own** legacy env names are removed — rename them: - -| removed | use | -|---|---| -| `OS_MULTI_TENANT` | `OS_MULTI_ORG_ENABLED` | -| `OBJECTSTACK_METADATA_WRITABLE` | `OS_METADATA_WRITABLE` | -| `OS_AUTH_BASE_URL`, `AUTH_BASE_URL` | `OS_AUTH_URL` | - -**Ecosystem-standard names still work** (and no longer warn): `DATABASE_URL`, -`AUTH_SECRET`, `BETTER_AUTH_SECRET`, `BETTER_AUTH_URL`, `PORT`, `CORS_*`, -`LOG_LEVEL`, `ROOT_DOMAIN`, `MCP_SERVER_*`. - -## `PolicySchema` / `definePolicy` removed - -The "org security policy" schema (`PolicySchema`, `definePolicy`, and the stack -`policies` collection) is removed — it was parsed but **never enforced** at runtime -(ADR-0049). `better-auth` governs session/password behavior; there is no functional -loss. - -**Migration**: delete `policies: [...]` from `defineStack(...)` and any -`definePolicy(...)` definitions. For real password/session policy, configure -`@objectstack/plugin-auth`. `SharingRule` / `PermissionSet` / RLS are unaffected. - ---- - -## Behavioral changes to be aware of (not API-breaking) - -11 also hardens authentication (ADR-0069). These don't change your code but can -change runtime behavior for end users: - -- Breached passwords are rejected (HIBP). -- Account lockout + login rate-limiting. -- Optional password expiry, history/no-reuse, complexity, and enforced MFA - (per-org). Review your `@objectstack/plugin-auth` configuration before rollout. - -## Getting help - -If a removed adapter or API blocks you, open an issue — thin adapters and the -`HttpDispatcher` API are public, so out-of-tree maintenance is straightforward. diff --git a/docs/v17-docs-sweep.md b/docs/v17-docs-sweep.md deleted file mode 100644 index 63495816bc1..00000000000 --- a/docs/v17-docs-sweep.md +++ /dev/null @@ -1,193 +0,0 @@ -# v17 docs sweep — log and playbook - -The v17 train is still accumulating changesets, so the docs cannot be aligned -once and declared done — they need **re-sweeping until `changeset pre exit`**. -This file is both the playbook for running a sweep and the append-only log of -every run, so the next sweep (human or agent) starts from a watermark instead -of re-auditing everything. - -Scope: hand-written prose — `content/docs/**` (excluding `references/`, which -regenerates from spec, and `releases/`, which *documents* the old shapes on -purpose) and `skills/**`. Note `content/docs/ai/skills-reference.mdx` and -`skills/README.md` are **generated** from `skills/*/SKILL.md` -(`pnpm --filter @objectstack/spec gen:skill-docs`) — fix the SKILL.md, then -regenerate; never edit the mirrors. - -## How to run a sweep - -1. Read the changesets added since the last run's watermark: - `git diff --name-only --diff-filter=A ..HEAD -- '.changeset/*.md'` - Extract every **removed / renamed / re-defaulted** surface (the `!:` entries - first, but minors retire surfaces too under the launch-window convention). -2. Extend the fingerprint table below with any new removals, then grep each - fingerprint over the scope. Judge every hit in context — a hit that - *documents the removal* is correct; a hit that *teaches the removed surface* - is drift. -3. Fix drift at the source (SKILL.md before its mirrors), regenerate, run: - `pnpm check:release-notes check:doc-authoring check:role-word` and - `pnpm docs:build`. -4. Append a run entry at the bottom: watermark, fingerprints added, files - fixed, false positives (so the next run can skip re-judging them), and - out-of-scope findings (file an issue per Prime Directive #10). - -Complementary deep pass: the fingerprint grep above is cheap and targeted at -*removals*; for a full implementation-accuracy re-verification of prose that -merely *references* changed code, use the `docs-accuracy-audit` workflow the -`docs-drift-check` PR bot advertises — scope it with -`node scripts/docs-audit/affected-docs.mjs ` and pass the list as -`args.docs`. Worth one scoped run before `changeset pre exit`. - -## Fingerprints (v17 removals/renames → what a hit means) - -| Pattern | Drift if the doc… | Source changeset | -|---|---|---| -| `conditionalRequired` | teaches it instead of `requiredWhen` | retire-three-deprecated-aliases | -| `action.execute` (as authored key) | teaches it instead of `target` | retire-three-deprecated-aliases | -| `knowledge.topics` | teaches it instead of `sources` | retire-three-deprecated-aliases | -| `agent.tools` / inline tool arrays on agents | teaches the removed slot instead of `skills` | ai-agent-authoring-and-tools-removal | -| `tool.requiresConfirmation` (on **AIToolSchema**) | teaches the removed flag — the action-level `ai.requiresConfirmation` **survives**, do not "fix" it | tool-requires-confirmation-removed | -| `ai.nlq` / `ai.suggest` / `ai.insights` | presents the phantom SDK surface as callable | remove-dead-sdk-surface | -| `client.permissions/realtime/workflow/views` CRUD, notifications device/preference, `listTemplates`, `--template` | presents removed SDK/CLI surface | remove-dead-client-surfaces, drop-dead-* | -| GraphQL as *our* API surface (`/graphql`, `handleGraphQL`, "REST/GraphQL endpoints", `graphql` service, `plugin-graphql`) | advertises the removed surface — external-datasource `'graphql'` protocol and generic industry mentions are **not** drift | remove-graphql-surface | -| `ObjectStackProtocol` (interface/schema) | presents the dissolved alias as the contract | v17-dissolve-protocol-alias | -| `enable.trash` / `enable.mru` | says the flag *exists* (even as "exists but unenforced") | remove-enable-trash-mru | -| legacy `apiMethods` values (`upsert`, `aggregate`, `search`, `history`, `restore`, `purge`, `import`, `export` **inside an apiMethods list**) | teaches authoring them | apimethod-enum-shrink | -| sharing `accessLevel: 'full'`, recipient `group` / `guest`, owner-type rules | presents them as authorable, or as "declared but not enforced" (they no longer parse) | sharing-rule-recipient-reconcile, fix(sharing) #3865 | -| `allowExport` unset ⇒ export allowed | claims export inherits read | export-axis-opt-in | -| `SkillSchema.permissions` | teaches the removed field | prune-skill-permissions | -| Node `18` as a floor | states an out-of-date prerequisite | engines-node-22 | -| `PortalSchema`, `AuditConfig`, Capabilities-descriptor cluster, `FeatureFlagSchema`, `DEFAULT_*_ROUTES`, report `aria`/`performance`, `ReportColumn/GroupingSchema` | teaches a pruned cluster | prune-* family | -| `GetTranslationsRequest` `namespace`/`keys` filters | teaches the dropped filters | i18n-translations-request-drop-phantom-filters | -| `` `@objectstack/spec` 18 `` (any v17 removal dated to **18**) | dates a removal that ships in **17** to the next major — the reader plans for it a release late and their upgrade breaks. Check the *number*, not just the surface name: `spec-changes.json` `toMajor` is the arbiter | #4286, #3963 | - -## Run log - -### 2026-07-29 — run 1 (baseline) - -- **Watermark:** framework `a641d10` (origin/main, post-#3906) · 305 changesets - present · objectui pin `4a4829d0ef39`. -- **Fixed (drift → corrected):** - - `kernel/services-checklist.mdx` — claimed 17 kernel services incl. - `graphql` and governance by the `ObjectStackProtocol` interface; now 16 - services, per-domain contracts, all graphql rows/diagram entries removed, - `plugin-ai` row no longer names the phantom NLQ/suggest/insights surface. - - `permissions/authorization.mdx` — anonymous-deny row listed `/graphql` + - `handleGraphQL` (removed from the matrix in v17); gate 4 said owner-type - rules are "declared but seed-skipped" (they no longer parse). - - `permissions/permissions-matrix.mdx` — sharing enforcement status still - described the pre-#1878 declared-but-skipped posture. - - `permissions/index.mdx` — status blurb said `group` recipients are - "declared but not enforced" (renamed to `team`; owner/`guest` pruned). - - `protocol/kernel/http-protocol.mdx` — said `enable.trash` "exists as an - object flag" (removed in v17; authoring it is now a parse error). - - `protocol/objectql/index.mdx`, `protocol/objectql/schema.mdx`, - `permissions/field-level-security.mdx` — "REST/GraphQL" in diagrams, - comments and prose. - - `skills/objectstack-api/SKILL.md` — description advertised "REST/GraphQL - endpoints" and a "REST/GraphQL generator"; mirrors regenerated - (`content/docs/ai/skills-reference.mdx`, `skills/README.md`). -- **Judged, not drift (skip re-checking):** - - `data-modeling/fields.mdx` (documents the `conditionalRequired` removal), - `data-modeling/objects.mdx` `apiMethods` row, `api/plugin-endpoints.mdx` - (documents the nlq/suggest/insights inversion), `api/client-sdk.mdx`, - `permissions/permission-sets.mdx` + `sharing-rules.mdx` (already teach the - v17 posture) — all corrected at change time by their changesets. - - `ai.requiresConfirmation` hits in `ai/connect-mcp.mdx`, - `ai/actions-as-tools.mdx`, `protocol/objectui/actions.mdx` — the surviving - action-level key, not the removed tool-level one. - - `automation/webhooks.mdx` "GraphQL subscriptions" — an out-of-scope - comparison in a "what this is not" list, not our surface. - - `ExecutionContext.tenantId` mentions — the internal field survives; only - the hook/action `ctx.tenantId` alias was removed (v16). -- **Out of scope, logged for follow-up:** - - `packages/spec/src/system/core-services.zod.ts` — the `'ai'` enum member's - comment still reads "AI Engine (NLQ, Chat, Suggest, Insights)"; comment-only - spec fix, belongs in a spec-touching PR. - - `content/docs/releases/implementation-status.mdx` — "Last Updated June - 2026", predates the whole v17 window; needs a regeneration pass of its own - rather than spot fixes. -- **Not yet swept:** `examples/**` inline prose and `docs/**` (internal); - lower-priority — user-facing `content/docs` + `skills` covered first. - -### 2026-08-01 — run 3 (version-number pass, #4476) - -- **Watermark:** framework `0f9faa2` (origin/main, post-#4489). -- **Fingerprint added:** the `@objectstack/spec` 18 row above. Runs 1-2 matched on - *surface names* and so read straight past a passage that named the right surface - and the wrong release. The number is the actionable half of a removal notice. -- **Fixed (drift → corrected):** 17 passages dating v17 removals to 18 → 17. - `spec-changes.json` gives `toMajor: 17` for all five surfaces involved, and this - tree is `17.0.0-rc.1` / `PROTOCOL_VERSION = '17.0.0'` with the keys already - `[RETIRED]` in `authorable-surface.json` — a removal cannot already be retired in - a 17 build and also ship in 18. - - `protocol/objectql/query-syntax.mdx` (5) · `data-modeling/queries.mdx` (4) · - `deployment/troubleshooting.mdx` (1) — the #4286 query surfaces. - - `skills/objectstack-query/SKILL.md` (3), `rules/aggregation.md` (1), - `rules/pagination.md` (1) — same wrong number in the **agent-facing** skill, - which #4476's fingerprint list did not cover. Highest-leverage of the set: an - agent authoring queries reads these as ground truth. - - `releases/implementation-status.mdx` (2) — same error shape on a *different* - change, `api.requireAuth` (#3963), also `toMajor: 17`. -- **Method note for the next run:** #4476 listed nine locations; a bare-pattern grep - found seventeen. Grep the pattern repo-wide (including `skills/`), do not work a - fingerprint list file-by-file. - -### 2026-08-02 — run 4 (rc.1 catch-up; closes the run-2 gap) - -- **Watermark:** framework `ff17642` (origin/main, post-#4590) · spec - `17.0.0-rc.1` · `PROTOCOL_VERSION = '17.0.0'`. -- **Coverage note:** the log holds run 1 (`a641d10`) and run 3 (version-number - pass only) — **no run 2 exists**, so the 362 changesets added - `a641d10..0f9faa2` had never been swept with removal fingerprints. This run's - delta is therefore `a641d10..HEAD` (435 new changesets, ~48 breaking), not - just the run-3 watermark. -- **Fingerprints added:** `api.requireAuth` (retired outright, #3963 — a doc - presenting the opt-out as available is drift); `workflow` kernel service slot - (#4451); standalone `validation` metadata kind (#4509, ADR-0088); `job` - runtime create/org override (#4509); flow `script` `config.actionType` / - `.template` / `.recipients` / `.variables` / inline `script` (#4343); - `query.cursor` / `query.distinct` / `joins` / `windowFunctions` / - nested-select (#4286, #4196); `EnhancedApiError.fieldErrors` (ADR-0114 D4); - `BatchOptions.validateOnly` (#4052); `registerStandardEndpoints` (#4073); - `readReplicas` (#4481); connector template / trigger-registry Connector - clusters (#4500, #4503); dual-source names (`WebhookConfig` from `./api`, - `CacheStrategyEnum`, `MetadataFormat` `'yml'/'ts'/'js'` aliases, - contracts `ShareRecipientType` → `RecordShareRecipientType`; #4537–#4539, - #4572). -- **Fixed (drift → corrected):** - - `permissions/authorization.mdx` — gate 1 still said serving the data plane - publicly "requires an explicit `api.requireAuth: false` opt-out"; the - opt-out is retired and tombstoned (#3963). - - `permissions/explain.mdx` — "even on `requireAuth: false` deployments", a - posture that no longer exists. - - `ui/forms.mdx` — two mentions of configuring `requireAuth`; rewritten - against the unconditional anonymous-deny posture. - - `kernel/services-checklist.mdx` — partially updated at change time: §6 and - the provider callout documented the `workflow` retirement, but the page - still claimed **16** services, listed `workflow` in the architecture - diagram, and carried its live row in the summary table. Now 15 services, - row removed, tables and section numbering re-aligned (enum verified: - 15 members). -- **Judged, not drift (skip re-checking):** `actionType` in - `deployment/validating-metadata.mdx` / `skills/objectstack-ui` (dashboard - action buttons — same key name, different surface); flows.mdx / automation - skill (document the #4343 retirement); `bulkActionDefs` in ui docs (teach - the new typed shape, #4457); `having` (documents "enforced since #4286"); - `fieldErrors` in api docs (documents the tombstone); `windowFunctions` / - `query.distinct` hits (all "removed in spec 17" notices, run 3 fixed their - version numbers); `maxRetries` in flows.mdx (explicit count — the required - posture, #4247). -- **Zero-hit fingerprints (nothing to fix):** `validateOnly`, - `registerStandardEndpoints`, `readReplicas`, `CacheStrategyEnum`, - `WebhookConfig`, `MetadataFormat` aliases, `ShareRecipientType`, standalone - `.validation.ts`, job `allowRuntimeCreate`, connector template cluster, - `storage.notNull` misclaims, plugin lifecycle-hook family. -- **Method note:** docs-at-change-time discipline improved markedly in this - window — most removals landed with their retirement callouts already written - (flows.mdx #4343, query-syntax #4286, error-catalog ADR-0114). The drift - that survives is the *second-order* kind: a page partially updated (checklist - count vs narrative) or a cross-reference in a page the change didn't touch - (requireAuth in explain/forms). Grep the fingerprint repo-wide even when the - primary page looks done. - - diff --git a/packages/metadata/ROADMAP.md b/packages/metadata/ROADMAP.md index 1a2f45c64c6..ea32946a5f1 100644 --- a/packages/metadata/ROADMAP.md +++ b/packages/metadata/ROADMAP.md @@ -238,4 +238,3 @@ artifact persistence (`artifacts/${projectId}/${commitId}.json`). - [Root ROADMAP](../../ROADMAP.md) — Full platform evolution (v3.0 → v5.0) - [Studio ROADMAP](../../apps/studio/ROADMAP.md) — Visual IDE development phases - [Metadata Service Protocol](../../content/docs/protocol/kernel/metadata-service.mdx) — Detailed protocol documentation -- [DX ROADMAP](../../docs/DX_ROADMAP.md) — Developer experience improvements diff --git a/packages/services/service-automation/src/engine.ts b/packages/services/service-automation/src/engine.ts index f9bc84e40a4..674882c4cc6 100644 --- a/packages/services/service-automation/src/engine.ts +++ b/packages/services/service-automation/src/engine.ts @@ -810,7 +810,8 @@ export type FlowRecordExpander = ( /** * Default ceiling on the in-memory execution-log ring buffer. Execution logs are - * process-local and diagnostic only (launch-readiness.md P1-2); the buffer keeps + * process-local and diagnostic only (launch-readiness P1-2, in + * `docs/launch-readiness.md` as of commit df8aac41); the buffer keeps * the most recent N entries and evicts the oldest, so memory is bounded * regardless of throughput. Operators tune the window via * {@link AutomationServicePluginOptions.maxLogSize}. Durable, queryable run diff --git a/packages/services/service-automation/src/plugin.ts b/packages/services/service-automation/src/plugin.ts index 7c30460d779..f8d90b9c0a2 100644 --- a/packages/services/service-automation/src/plugin.ts +++ b/packages/services/service-automation/src/plugin.ts @@ -132,7 +132,8 @@ export interface AutomationServicePluginOptions { /** * Max in-memory execution-log entries retained per process (ring buffer; * oldest evicted). The buffer is diagnostic-only and already bounded - * (launch-readiness.md P1-2); this just makes the window tunable. Defaults + * (launch-readiness P1-2, in `docs/launch-readiness.md` as of commit + * df8aac41); this just makes the window tunable. Defaults * to {@link DEFAULT_MAX_EXECUTION_LOG_SIZE} (1000). */ maxLogSize?: number; diff --git a/packages/services/service-realtime/src/in-memory-realtime-adapter.ts b/packages/services/service-realtime/src/in-memory-realtime-adapter.ts index e20f368fb33..87b4af0cbdf 100644 --- a/packages/services/service-realtime/src/in-memory-realtime-adapter.ts +++ b/packages/services/service-realtime/src/in-memory-realtime-adapter.ts @@ -19,7 +19,8 @@ interface Subscription { /** * Default safety cap on active subscriptions. This adapter is process-local - * (the v1 single-instance contract — see launch-readiness.md P0-5); an + * (the v1 single-instance contract — launch-readiness P0-5, in + * `docs/launch-readiness.md` as of commit df8aac41); an * unbounded subscription map would grow until the pod OOMs under a subscription * leak or an abusive client. The cap is a backstop: `subscribe` throws once * it's reached. Operators raise `maxSubscriptions` for high-fan-out nodes; diff --git a/packages/services/service-realtime/src/realtime-service-plugin.ts b/packages/services/service-realtime/src/realtime-service-plugin.ts index 7276ba56809..a766eb8712a 100644 --- a/packages/services/service-realtime/src/realtime-service-plugin.ts +++ b/packages/services/service-realtime/src/realtime-service-plugin.ts @@ -21,7 +21,8 @@ export interface RealtimeServicePluginOptions { * Registers a realtime pub/sub service with the kernel during the init phase. * Currently supports in-memory pub/sub for single-process environments. * - * **v1 deployment contract (launch-readiness.md P0-5): single-instance only.** + * **v1 deployment contract (launch-readiness P0-5): single-instance only.** The + * contract's source is `docs/launch-readiness.md` as of commit df8aac41. * The in-memory adapter is process-local — events published on node A are not * delivered to subscribers on node B. A default `maxSubscriptions` safety cap is * enforced (see {@link InMemoryRealtimeAdapter}) so the subscription map can't diff --git a/packages/spec/scripts/build-docs.ts b/packages/spec/scripts/build-docs.ts index 53cd2957c39..937998e6ace 100644 --- a/packages/spec/scripts/build-docs.ts +++ b/packages/spec/scripts/build-docs.ts @@ -10,7 +10,6 @@ // // Hand-written documentation lives in the module folders under content/docs/ // (data-modeling/, automation/, permissions/, ui/, api/, ai/, plugins/, kernel/, ...). -// See DX_ROADMAP.md and .cursorrules for details. // // Usage: // tsx scripts/build-docs.ts # write diff --git a/scripts/check-doc-authoring.mjs b/scripts/check-doc-authoring.mjs index b25b18a0a42..e1b09d2ea41 100644 --- a/scripts/check-doc-authoring.mjs +++ b/scripts/check-doc-authoring.mjs @@ -49,7 +49,7 @@ // #4913 took `.claude` rather than `.claude/skills`: a new subdirectory under it // is covered on arrival instead of being missed the same way twice. That also // covers the hand-written top-level guides (`docs/protocol-upgrade-guide.md`, -// `docs/upgrading-to-11.md`, …), which are live instructions to the reader and +// `docs/releases-maintenance.md`, …), which are live instructions to the reader and // belong in scope. // // ## Dead roots are a hard error (#4916) @@ -204,8 +204,8 @@ const SKIP_FILES = new Set(['content/docs/ai/skills-reference.mdx']); * the top of this file: a new subdirectory is covered on arrival instead of * being missed the same way twice — and a declaration that has to be extended * by hand is the same silent narrowing, one tool over. And it strands the - * twelve hand-written top-level guides (`docs/protocol-upgrade-guide.md`, - * `docs/upgrading-to-11.md`, …), which are files rather than a subtree and + * hand-written top-level guides (`docs/protocol-upgrade-guide.md`, + * `docs/releases-maintenance.md`, …), which are files rather than a subtree and * would have to be enumerated one literal each. * * The residual is also not new: those four subtrees derive this gate TODAY, via diff --git a/scripts/check-platform-checklist.mjs b/scripts/check-platform-checklist.mjs index 9e4b2cc317c..291bf9eab41 100644 --- a/scripts/check-platform-checklist.mjs +++ b/scripts/check-platform-checklist.mjs @@ -7,7 +7,8 @@ // ## The failure this exists for // // Release verification used to live in one-off surfaces: a hand-written table -// per release (docs/plans/release-15.1-test-plan.md) and a checkbox issue per +// per release (docs/plans/release-15.1-test-plan.md, as of commit df8aac41) and +// a checkbox issue per // release (#3358). Both worked once and then rotted: items could not be reused // across releases, results were checkboxes with no revision to pin them to, and // every fixture gap the run discovered (#3408 phone persona never seeded, #3409 diff --git a/scripts/check-required-contexts.mjs b/scripts/check-required-contexts.mjs index 428a4ec0797..c744b5394f1 100644 --- a/scripts/check-required-contexts.mjs +++ b/scripts/check-required-contexts.mjs @@ -545,7 +545,7 @@ export const REQUIRED_CONTEXTS = [ * registry EXACTLY, so the NEXT enrolment cannot land without following the * sentence. RESIDUALS, recorded rather than implied covered: paraphrase * drift (naming a context loosely, e.g. "Lint & Type Check" in - * docs/launch-readiness.md) is invisible to both halves; and after a + * docs/launch-readiness.md as of commit df8aac41) is invisible to both halves; and after a * SHORTENING rename (new name a substring of the old), an old-literal mention * satisfies the new name's `mustName` by substring — the budget half still * tracks the old name, so staleness stays bounded; and the COUNT WORD that @@ -639,7 +639,6 @@ export const INSTRUCTION_SURFACES = [ mustName: [], }, // Release/maintenance checklists that name individual contexts ⇒ scan-only. - { file: 'docs/launch-readiness.md', mustName: [] }, { file: 'docs/releases-maintenance.md', mustName: [] }, ];