Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29815c49b8 | ||
|
|
c14ad7fd0b |
@@ -179,6 +179,30 @@
|
||||
"database_schema": "interaction",
|
||||
"boundary_class": "remote_capable",
|
||||
"may_depend_on": ["contracts.identity", "contracts.situation", "contracts.epistemics", "contracts.cognitive", "platform.ids", "platform.events"]
|
||||
},
|
||||
"world": {
|
||||
"id": "mod.world",
|
||||
"owns": ["WorldObject", "WorldObjectKindDefinition", "WorldAlias", "FacetDefinition", "RelationDefinition", "IdentityResolutionCandidate", "IdentityResolutionDecision", "WorldLineage"],
|
||||
"database_schema": "world",
|
||||
"boundary_class": "remote_capable",
|
||||
"may_depend_on": ["contracts.identity", "platform.ids", "platform.events"],
|
||||
"forbidden": ["adapters.models", "adapters.temporal", "claims", "beliefs", "observations"]
|
||||
},
|
||||
"configuration": {
|
||||
"id": "mod.configuration",
|
||||
"owns": ["SettingDefinition", "SettingAssignment", "ConfigurationRevision", "ConfigurationChangeProvenance"],
|
||||
"database_schema": "configuration",
|
||||
"boundary_class": "remote_capable",
|
||||
"may_depend_on": ["contracts.identity", "contracts.authority", "platform.ids", "platform.events", "platform.secrets"],
|
||||
"forbidden": ["secret_values", "arbitrary_key_value_without_definition"]
|
||||
},
|
||||
"self": {
|
||||
"id": "mod.self",
|
||||
"owns": ["CompetenceAssessment", "WeaknessPattern", "DependencyAssessment", "LearningLedgerEntry", "ImprovementNeed", "SelfVersionView", "SelfEvaluationInterpretation"],
|
||||
"database_schema": "self",
|
||||
"boundary_class": "remote_capable",
|
||||
"may_depend_on": ["contracts.capability", "contracts.epistemics", "contracts.artifact", "platform.ids", "platform.events"],
|
||||
"forbidden": ["adapters.models", "tasks", "authority_grants", "code_release_switching"]
|
||||
}
|
||||
},
|
||||
"platform": {
|
||||
@@ -244,6 +268,26 @@
|
||||
"cross_owner_write": "forbidden",
|
||||
"cross_owner_application_join": "forbidden"
|
||||
},
|
||||
"runtime_topology_v2": {
|
||||
"core_runtime": {
|
||||
"modules": ["identity", "situation", "work", "epistemics", "capability", "artifact", "interaction", "world", "configuration", "self"]
|
||||
},
|
||||
"continuity_runtime": {"modules": ["continuity"]},
|
||||
"commit_runtime": {"modules": ["authority", "commit"]},
|
||||
"cognitive_workers": {"modules": [], "role": "replaceable reasoning/context workers; no canonical ownership"},
|
||||
"supervisor_runtime": {"modules": [], "role": "release health, switch, rollback and recovery; not a semantic owner"}
|
||||
},
|
||||
"storage_topology_v2": {
|
||||
"postgres_cluster": "assistant_primary",
|
||||
"schemas": {
|
||||
"identity": "identity_role", "authority": "authority_role", "situation": "situation_role", "work": "work_role",
|
||||
"epistemics": "epistemics_role", "continuity": "continuity_role", "capability": "capability_role", "commit": "commit_role",
|
||||
"artifact": "artifact_role", "interaction": "interaction_role", "world": "world_role", "configuration": "configuration_role", "self": "self_role"
|
||||
},
|
||||
"cross_owner_fk": "forbidden_by_default",
|
||||
"cross_owner_write": "forbidden",
|
||||
"cross_owner_application_join": "forbidden"
|
||||
},
|
||||
"invariants": [
|
||||
{
|
||||
"id": "INV-AUTH-001",
|
||||
@@ -309,6 +353,14 @@
|
||||
".gitea/workflows/ci.yml",
|
||||
"cmd/devctl/**",
|
||||
"dev/ACTIVE_TASK.json",
|
||||
"docs/DOMOVOY_CONSTITUTION.md",
|
||||
"docs/DOMOVOY_GEN2_GAP_MAP.md",
|
||||
"architecture/GEN2_TARGET_ARCHITECTURE.md",
|
||||
"architecture/GEN2_CANONICAL_DATA_MODEL.md",
|
||||
"development/GEN2_MIGRATION_MAP.md",
|
||||
"development/GEN2_MASTER_PLAN.md",
|
||||
"development/GEN2_EXECUTION_CONTRACT.md",
|
||||
"development/GEN2_TASK_INDEX.md",
|
||||
"security/**"
|
||||
],
|
||||
"default_feature_task_authority": {
|
||||
|
||||
@@ -75,6 +75,30 @@ modules:
|
||||
boundary_class: remote_capable
|
||||
may_depend_on: [contracts.identity, contracts.situation, contracts.epistemics, contracts.cognitive, platform.ids, platform.events]
|
||||
|
||||
world:
|
||||
id: mod.world
|
||||
owns: [WorldObject, WorldObjectKindDefinition, WorldAlias, FacetDefinition, RelationDefinition, IdentityResolutionCandidate, IdentityResolutionDecision, WorldLineage]
|
||||
database_schema: world
|
||||
boundary_class: remote_capable
|
||||
may_depend_on: [contracts.identity, platform.ids, platform.events]
|
||||
forbidden: [adapters.models, adapters.temporal, claims, beliefs, observations]
|
||||
|
||||
configuration:
|
||||
id: mod.configuration
|
||||
owns: [SettingDefinition, SettingAssignment, ConfigurationRevision, ConfigurationChangeProvenance]
|
||||
database_schema: configuration
|
||||
boundary_class: remote_capable
|
||||
may_depend_on: [contracts.identity, contracts.authority, platform.ids, platform.events, platform.secrets]
|
||||
forbidden: [secret_values, arbitrary_key_value_without_definition]
|
||||
|
||||
self:
|
||||
id: mod.self
|
||||
owns: [CompetenceAssessment, WeaknessPattern, DependencyAssessment, LearningLedgerEntry, ImprovementNeed, SelfVersionView, SelfEvaluationInterpretation]
|
||||
database_schema: self
|
||||
boundary_class: remote_capable
|
||||
may_depend_on: [contracts.capability, contracts.epistemics, contracts.artifact, platform.ids, platform.events]
|
||||
forbidden: [adapters.models, tasks, authority_grants, code_release_switching]
|
||||
|
||||
platform:
|
||||
allowed_packages:
|
||||
- platform.ids
|
||||
@@ -98,6 +122,20 @@ runtime_topology_v1:
|
||||
modules: []
|
||||
role: "replaceable cognition/context compilation workers; no canonical ownership"
|
||||
|
||||
runtime_topology_v2:
|
||||
core_runtime:
|
||||
modules: [identity, situation, work, epistemics, capability, artifact, interaction, world, configuration, self]
|
||||
continuity_runtime:
|
||||
modules: [continuity]
|
||||
commit_runtime:
|
||||
modules: [authority, commit]
|
||||
cognitive_workers:
|
||||
modules: []
|
||||
role: "replaceable reasoning/context workers; no canonical ownership"
|
||||
supervisor_runtime:
|
||||
modules: []
|
||||
role: "release health, switch, rollback and recovery; not a semantic owner"
|
||||
|
||||
storage_topology_v1:
|
||||
postgres_cluster: assistant_primary
|
||||
schemas:
|
||||
@@ -115,6 +153,26 @@ storage_topology_v1:
|
||||
cross_owner_write: forbidden
|
||||
cross_owner_application_join: forbidden
|
||||
|
||||
storage_topology_v2:
|
||||
postgres_cluster: assistant_primary
|
||||
schemas:
|
||||
identity: identity_role
|
||||
authority: authority_role
|
||||
situation: situation_role
|
||||
work: work_role
|
||||
epistemics: epistemics_role
|
||||
continuity: continuity_role
|
||||
capability: capability_role
|
||||
commit: commit_role
|
||||
artifact: artifact_role
|
||||
interaction: interaction_role
|
||||
world: world_role
|
||||
configuration: configuration_role
|
||||
self: self_role
|
||||
cross_owner_fk: forbidden_by_default
|
||||
cross_owner_write: forbidden
|
||||
cross_owner_application_join: forbidden
|
||||
|
||||
invariants:
|
||||
- id: INV-AUTH-001
|
||||
property: "No external mutation without current valid authority and target/revision checks"
|
||||
@@ -149,6 +207,14 @@ protected_paths:
|
||||
- .gitea/workflows/ci.yml
|
||||
- cmd/devctl/**
|
||||
- dev/ACTIVE_TASK.json
|
||||
- docs/DOMOVOY_CONSTITUTION.md
|
||||
- docs/DOMOVOY_GEN2_GAP_MAP.md
|
||||
- architecture/GEN2_TARGET_ARCHITECTURE.md
|
||||
- architecture/GEN2_CANONICAL_DATA_MODEL.md
|
||||
- development/GEN2_MIGRATION_MAP.md
|
||||
- development/GEN2_MASTER_PLAN.md
|
||||
- development/GEN2_EXECUTION_CONTRACT.md
|
||||
- development/GEN2_TASK_INDEX.md
|
||||
- security/**
|
||||
|
||||
default_feature_task_authority:
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# Configuration contract boundary
|
||||
|
||||
Configuration owns typed and versioned `SettingDefinition` and
|
||||
`SettingAssignment` records plus scoped resolution and change provenance.
|
||||
Effective configuration is a derived result. Secret values never enter a
|
||||
setting assignment; only a `SecretRef`/`CredentialRef` crosses the secrets
|
||||
boundary into an authorized adapter or runtime.
|
||||
@@ -0,0 +1,7 @@
|
||||
package configuration
|
||||
|
||||
import "git.cin.su/m/Assistant/platform/ids"
|
||||
|
||||
// SemanticReference is a typed cross-owner reference; settings remain
|
||||
// Configuration-owned records.
|
||||
type SemanticReference = ids.SemanticRef
|
||||
@@ -0,0 +1,7 @@
|
||||
package epistemics
|
||||
|
||||
import "git.cin.su/m/Assistant/platform/ids"
|
||||
|
||||
// SemanticReference identifies evidence-related records without transferring
|
||||
// canonical ownership to Epistemics.
|
||||
type SemanticReference = ids.SemanticRef
|
||||
@@ -0,0 +1,9 @@
|
||||
# SELF contract boundary
|
||||
|
||||
SELF owns evidence-backed competence, weakness, dependency, learning, and
|
||||
self-evaluation records. Raw evidence remains Epistemics-owned; capability
|
||||
health remains Capability-owned; tasks and development remain Work-owned;
|
||||
release switching remains Supervisor/runtime-owned.
|
||||
|
||||
SELF is observational/evaluative and is not a mandatory request-path
|
||||
orchestrator or an authority source.
|
||||
@@ -0,0 +1,7 @@
|
||||
package self
|
||||
|
||||
import "git.cin.su/m/Assistant/platform/ids"
|
||||
|
||||
// SemanticReference lets SELF cite evidence and capabilities without owning
|
||||
// their canonical state.
|
||||
type SemanticReference = ids.SemanticRef
|
||||
@@ -0,0 +1,7 @@
|
||||
package situation
|
||||
|
||||
import "git.cin.su/m/Assistant/platform/ids"
|
||||
|
||||
// SemanticReference keeps Situation references transport-neutral while
|
||||
// ContextScope semantics remain owned by Situation.
|
||||
type SemanticReference = ids.SemanticRef
|
||||
@@ -0,0 +1,9 @@
|
||||
# World contract boundary
|
||||
|
||||
World owns typed, versioned referents and vocabulary: `WorldObject`, kind and
|
||||
facet/relation definitions, aliases, identity-resolution decisions, and
|
||||
merge/split lineage. It does not own observations, claims, beliefs, or the
|
||||
truth of values about a referent; those remain Epistemics-owned evidence.
|
||||
|
||||
Cross-owner references are typed semantic references. They do not create
|
||||
cross-owner foreign keys, joins, writes, or a generic `Entity(any)` API.
|
||||
@@ -0,0 +1,97 @@
|
||||
package world
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.cin.su/m/Assistant/platform/ids"
|
||||
)
|
||||
|
||||
// SemanticReference is the transport envelope used by World contracts. It is
|
||||
// a reference only; it does not expose another owner's storage.
|
||||
type SemanticReference = ids.SemanticRef
|
||||
|
||||
type PrincipalRealm string
|
||||
|
||||
const (
|
||||
RealmPersonal PrincipalRealm = "PERSONAL"
|
||||
RealmShared PrincipalRealm = "SHARED"
|
||||
RealmPublic PrincipalRealm = "PUBLIC"
|
||||
RealmSystem PrincipalRealm = "SYSTEM"
|
||||
)
|
||||
|
||||
type SensitivityClass string
|
||||
|
||||
const (
|
||||
SensitivityPublic SensitivityClass = "PUBLIC"
|
||||
SensitivityPrivate SensitivityClass = "PRIVATE"
|
||||
SensitivityRestricted SensitivityClass = "RESTRICTED"
|
||||
SensitivitySecretReference SensitivityClass = "SECRET_REFERENCE"
|
||||
)
|
||||
|
||||
type ValueTypeKind string
|
||||
|
||||
const (
|
||||
ValueString ValueTypeKind = "STRING"
|
||||
ValueInteger ValueTypeKind = "INTEGER"
|
||||
ValueDecimal ValueTypeKind = "DECIMAL"
|
||||
ValueBoolean ValueTypeKind = "BOOLEAN"
|
||||
ValueTime ValueTypeKind = "TIME"
|
||||
ValueDuration ValueTypeKind = "DURATION"
|
||||
ValueEnum ValueTypeKind = "ENUM"
|
||||
ValueReference ValueTypeKind = "REFERENCE"
|
||||
ValueBinaryRef ValueTypeKind = "BINARY_REF"
|
||||
ValueList ValueTypeKind = "LIST"
|
||||
ValueStruct ValueTypeKind = "STRUCT"
|
||||
)
|
||||
|
||||
type ValueField struct {
|
||||
Name string
|
||||
Type ValueTypeSpec
|
||||
}
|
||||
|
||||
type ValueTypeSpec struct {
|
||||
Kind ValueTypeKind
|
||||
Element *ValueTypeSpec
|
||||
Fields []ValueField
|
||||
EnumValues []string
|
||||
ReferenceKind string
|
||||
}
|
||||
|
||||
func (s ValueTypeSpec) Validate() error {
|
||||
if s.Kind == "" {
|
||||
return fmt.Errorf("value type kind is required")
|
||||
}
|
||||
switch s.Kind {
|
||||
case ValueList:
|
||||
if s.Element == nil {
|
||||
return fmt.Errorf("list element type is required")
|
||||
}
|
||||
return s.Element.Validate()
|
||||
case ValueStruct:
|
||||
if len(s.Fields) == 0 {
|
||||
return fmt.Errorf("struct fields are required")
|
||||
}
|
||||
seen := map[string]struct{}{}
|
||||
for _, field := range s.Fields {
|
||||
if field.Name == "" {
|
||||
return fmt.Errorf("struct field name is required")
|
||||
}
|
||||
if _, ok := seen[field.Name]; ok {
|
||||
return fmt.Errorf("duplicate struct field %q", field.Name)
|
||||
}
|
||||
seen[field.Name] = struct{}{}
|
||||
if err := field.Type.Validate(); err != nil {
|
||||
return fmt.Errorf("field %s: %w", field.Name, err)
|
||||
}
|
||||
}
|
||||
case ValueEnum:
|
||||
if len(s.EnumValues) == 0 {
|
||||
return fmt.Errorf("enum values are required")
|
||||
}
|
||||
case ValueReference:
|
||||
if s.ReferenceKind == "" {
|
||||
return fmt.Errorf("reference kind is required")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package world
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestValueTypeSpecValidatesTypedRecursiveShape(t *testing.T) {
|
||||
spec := ValueTypeSpec{Kind: ValueStruct, Fields: []ValueField{{Name: "name", Type: ValueTypeSpec{Kind: ValueString}}, {Name: "refs", Type: ValueTypeSpec{Kind: ValueList, Element: &ValueTypeSpec{Kind: ValueReference, ReferenceKind: "world.object"}}}}}
|
||||
if err := spec.Validate(); err != nil {
|
||||
t.Fatalf("ValueTypeSpec.Validate() = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestValueTypeSpecRejectsDuplicateFields(t *testing.T) {
|
||||
spec := ValueTypeSpec{Kind: ValueStruct, Fields: []ValueField{{Name: "same", Type: ValueTypeSpec{Kind: ValueString}}, {Name: "same", Type: ValueTypeSpec{Kind: ValueString}}}}
|
||||
if err := spec.Validate(); err == nil {
|
||||
t.Fatal("duplicate fields were accepted")
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"task_file": "dev/tasks/ARCH-GEN2-000-adopt-gen2-constitution-architecture-documents-and-governance-mode.json",
|
||||
"task_id": "ARCH-GEN2-000",
|
||||
"task_file": "dev/tasks/GEN2-002-introduce-shared-gen2-data-primitives-without-shared-domain-semantics.json",
|
||||
"task_id": "GEN2-002",
|
||||
"task_revision": 1
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package clock
|
||||
|
||||
import "time"
|
||||
|
||||
// Instant is a UTC point represented as Unix milliseconds.
|
||||
type Instant int64
|
||||
|
||||
func (i Instant) Valid() bool { return i > 0 }
|
||||
|
||||
func NowInstant() Instant { return FromTime(time.Now().UTC()) }
|
||||
|
||||
func FromTime(value time.Time) Instant { return Instant(value.UTC().UnixMilli()) }
|
||||
|
||||
func (i Instant) Time() time.Time { return time.UnixMilli(int64(i)).UTC() }
|
||||
@@ -0,0 +1,14 @@
|
||||
package clock
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestInstantRoundTripUsesUTCUnixMilliseconds(t *testing.T) {
|
||||
want := time.Date(2026, time.August, 29, 12, 34, 56, 789000000, time.FixedZone("local", 3*60*60))
|
||||
got := FromTime(want).Time()
|
||||
if !got.Equal(want.UTC()) || got.Location() != time.UTC {
|
||||
t.Fatalf("instant round trip = %v, want %v UTC", got, want.UTC())
|
||||
}
|
||||
}
|
||||
+34
-5
@@ -6,14 +6,43 @@ import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ID is a transport-neutral opaque identifier primitive. Domain packages wrap it
|
||||
// in strong semantic ID types; do not pass bare ID across semantic boundaries.
|
||||
type ID string
|
||||
// StableID is a transport-neutral opaque identifier primitive. Domain packages
|
||||
// wrap it in strong semantic ID types; do not pass bare StableID across
|
||||
// semantic boundaries.
|
||||
type StableID string
|
||||
|
||||
func New() (ID, error) {
|
||||
// ID is retained as a compatibility name for the V1 primitive.
|
||||
type ID = StableID
|
||||
|
||||
// Revision is the optimistic version of a versioned semantic record.
|
||||
type Revision uint64
|
||||
|
||||
const InitialRevision Revision = 1
|
||||
|
||||
func (r Revision) Valid() bool { return r >= InitialRevision }
|
||||
|
||||
// SemanticRef is a technical cross-owner reference envelope. It identifies a
|
||||
// record but does not grant storage ownership or provide generic CRUD.
|
||||
type SemanticRef struct {
|
||||
OwnerNamespace string
|
||||
SemanticKind string
|
||||
StableID StableID
|
||||
Revision *Revision
|
||||
}
|
||||
|
||||
func (r SemanticRef) Valid() bool {
|
||||
return r.OwnerNamespace != "" && r.SemanticKind != "" && r.StableID != "" &&
|
||||
(r.Revision == nil || r.Revision.Valid())
|
||||
}
|
||||
|
||||
func NewStableID() (StableID, error) {
|
||||
var b [16]byte
|
||||
if _, err := rand.Read(b[:]); err != nil {
|
||||
return "", fmt.Errorf("generate id: %w", err)
|
||||
}
|
||||
return ID(hex.EncodeToString(b[:])), nil
|
||||
return StableID(hex.EncodeToString(b[:])), nil
|
||||
}
|
||||
|
||||
func New() (ID, error) {
|
||||
return NewStableID()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package ids
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestNewStableIDIsOpaque128BitHex(t *testing.T) {
|
||||
id, err := NewStableID()
|
||||
if err != nil || len(id) != 32 {
|
||||
t.Fatalf("NewStableID() = %q, %v", id, err)
|
||||
}
|
||||
if !(SemanticRef{OwnerNamespace: "world", SemanticKind: "object", StableID: id}.Valid()) {
|
||||
t.Fatal("stable id was not accepted by semantic reference")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSemanticRefRejectsInvalidRevision(t *testing.T) {
|
||||
revision := Revision(0)
|
||||
ref := SemanticRef{OwnerNamespace: "world", SemanticKind: "object", StableID: "id", Revision: &revision}
|
||||
if ref.Valid() {
|
||||
t.Fatal("semantic reference accepted invalid revision")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user