feat(settings): add user-settings seam (ctx.settings) + file provider
Two-package capability family mirroring session-persistence/: - dsh-settings: abstract Settings service — namespace registry with caller-fiber effect registrations, layered resolution (schema defaults < composition base < user document), schemastery validation, per-namespace deep-equal commit detection, and the settings/updated event. Boot/registration validation fails loud; provider publishes keep last-good per namespace. - dsh-settings-local: settings.yaml/.json provider — resolveSpec defaulting to $DSH_HOME/settings.yaml, chokidar hot reload, content-equality self-write suppression, atomic 0600 tmp+rename writes, comment-preserving YAML namespace patching. Consumers register inside ctx.inject(['settings'], …), so every composition works unchanged without a mounted provider. Real Loader + Include composition test proves cordis.yml boot and external-edit hot propagation; HMR disposal test proves registry cleanup. Both packages hold per-file 100% coverage. Doc budgets rise 1705→1710 (AGENTS.md) and 835→845 (packages/README.md): one structural line per file for the new package group. Agent Note: .agents/notes/implemented/architecture/2026-07-28-user-settings-seam.md
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"AGENTS.md": 1705,
|
||||
"AGENTS.md": 1710,
|
||||
"docs/AGENTS.md": 1150,
|
||||
"docs/architecture.md": 1800,
|
||||
"docs/cordis-primer.md": 600,
|
||||
@@ -7,5 +7,5 @@
|
||||
"docs/testing.md": 1100,
|
||||
"examples/AGENTS.md": 310,
|
||||
"packages/AGENTS.md": 675,
|
||||
"packages/README.md": 835
|
||||
"packages/README.md": 845
|
||||
}
|
||||
|
||||
@@ -217,6 +217,12 @@ const FOUNDATION_TYPE_NAMES = new Set([
|
||||
/** Project types deliberately documented outside the core-data catalog. */
|
||||
const TYPE_LINK_EXEMPTIONS: Readonly<Record<string, string>> = {
|
||||
AgentFactory: 'agent creation seam is owned by packages/core/agent/README.md',
|
||||
SettingsNamespace: 'settings seam vocabulary is owned by packages/settings/settings/README.md',
|
||||
SettingsUpdateSource: 'settings seam vocabulary is owned by packages/settings/settings/README.md',
|
||||
SettingsRegisterOptions: 'settings seam vocabulary is owned by packages/settings/settings/README.md',
|
||||
SettingsScope: 'settings seam vocabulary is owned by packages/settings/settings/README.md',
|
||||
SettingsDescriptor: 'settings seam vocabulary is owned by packages/settings/settings/README.md',
|
||||
z: 'schemastery schema constructor is owned by vendor/schemastery (vendored upstream)',
|
||||
BeginCommandRequest: 'event-local request contract is owned by packages/client/ui-slash/src/types.ts',
|
||||
InsertReferenceRequest: 'event-local request contract is owned by packages/client/ui-slash/src/types.ts',
|
||||
ConsumeTokenRequest: 'event-local request contract is owned by packages/client/ui-slash/src/types.ts',
|
||||
|
||||
@@ -137,6 +137,15 @@ const SERVICE_ROLES: ServiceRole[] = [
|
||||
consumers: ['agent-loop', 'tool-bash', 'hooks-claude', 'hooks-codex', 'session-query', 'session-query-sqlite'],
|
||||
note: 'Backends persist the same SessionEvent vocabulary; apps choose a backend at composition time.',
|
||||
},
|
||||
{
|
||||
key: 'settings',
|
||||
pkg: 'settings',
|
||||
title: 'User-settings seam',
|
||||
mode: 'seam',
|
||||
implementations: ['settings-local'],
|
||||
consumers: [],
|
||||
note: 'Plugins register namespace schemas and resolve layered values; providers store the raw document. No production consumer is migrated yet.',
|
||||
},
|
||||
{
|
||||
key: 'telemetry',
|
||||
pkg: 'session-telemetry',
|
||||
|
||||
@@ -90,6 +90,8 @@ const SENTENCE_MODEL_EXPERIENCE: Readonly<Record<string, SentenceContract>> = {
|
||||
'packages/sdk/telemetry': { kind: 'none', reason: 'The launcher-side reporter sends developer-cycle telemetry and registers no live agent or model surface.' },
|
||||
'packages/session-query/session-query': { kind: 'none', reason: 'The trusted query service exposes cloned records only to callers and registers no model surface.' },
|
||||
'packages/session-query/session-query-sqlite': { kind: 'none', reason: 'The search backend returns hits only to callers and registers no model surface.' },
|
||||
'packages/settings/settings': { kind: 'indirect', reason: 'The seam stores and resolves user settings; consumer plugins own any model surface a value feeds.' },
|
||||
'packages/settings/settings-local': { kind: 'indirect', reason: 'The file provider stores and publishes namespace sections; consumers of ctx.settings own any model surface.' },
|
||||
'packages/telemetry/session-telemetry': { kind: 'none', reason: 'The seam observes the session stream and hands redacted copies outward; it registers no model surface.' },
|
||||
'packages/telemetry/session-telemetry-otel': { kind: 'none', reason: 'The backend forwards seam records into the OTel SDK pipeline and registers no model surface.' },
|
||||
'packages/skill/skill': { kind: 'indirect', reason: 'The provider registry delegates model rendering to dsh-tool-skill.' },
|
||||
|
||||
Reference in New Issue
Block a user