Parent: #2635
Objective
Build the durable data foundation for transactional profiles: registry ownership/propagation metadata, typed ProfileDocumentV2, qualified repository identity, schema-derived redaction, and an automatic all-or-nothing v1→v2 generation migration.
This task is persistence/schema only. It does not introduce a second active-state owner, construct provider runtimes, or duplicate #2533's generic naming enforcement.
Scope
Registry taxonomy
- Inventory all canonical setting keys plus alias/unregistered stragglers.
- Classify owner: application or profile provider connection/behavior, model params/behavior, agent tools/shell/loops/compression.
- Classify propagation: render-immediate, next-turn, service-reconfigure, profile-transition, restart-required.
- Add sensitivity, persistence, default source, runtime impact, and canonical alias metadata.
- Remove
emojifilter, dumpcontext, dumponerror, and ui.showReasoning from profile persistence; add/wire application settings as required.
- Migrate reasoning context fields to one
reasoning.contextPolicy defaulting to preserve.
- Reconcile
compression-preserve-threshold, tool-format aliases/wire-format intent, and user context-limit versus catalog capacity.
Profile v2
Define strict standard/LB schemas with:
- stable provider implementation ID;
- typed provider connection/behavior;
- discriminated auth intent: key-name, keyfile, OAuth/buckets, provider-default, deprecated inline legacy secret;
- model identity, API params/behavior;
- explicit bounded JSON
provider.extensions and model.extensions only;
- agent tool/shell/loop/compression policy and qualified role references;
- unknown typed/top-level key rejection;
- separate internal raw document and redacted
ProfileDocumentView/diff serializers.
Repository identity and CRUD foundation
- Qualified stable IDs across user/project/extension scopes.
- Cross-platform canonical safe names; reject traversal/separators/controls/reserved names/Unicode normalization and case-fold collisions.
- Document bare-name precedence and fail ambiguity.
- Content etags, summaries, writable/trusted capability, reverse references.
- Atomic writes inside a generation; save-as/rename/delete reverse-validation; read-only source forking.
- Repository events for external modification/deletion without active-state ownership.
Migration/recovery
Implement a bounded LegacyProfileMigrationSource and generation/journal protocol:
- owner-verified interprocess lock (never stale-by-age alone);
- recovery before exposing profiles/settings;
- parse/convert all profiles and aggregate redacted errors;
- apply characterized legacy auth/naming/default precedence once;
- assign qualified IDs and resolve bare references under pinned precedence;
- validate the complete LB/compression/reference graph;
- coordinate moved application settings and profiles in one journal;
- restrictive immutable checksummed generation and UUID backup/manifest;
- atomic small-pointer commit and idempotent completion marker.
Support explicit read-only in-memory-v2 or strict-failure behavior. Fault-inject every staging/settings/pointer/completion boundary, concurrent startup, lock recovery, backup collision, and rollback. Normal repository consumers accept v2 only after durable activation. No automatic v1/v2 dual writes.
Coordination / non-overlap
Acceptance criteria
- Profile/runtime consumers can parse only strict v2; legacy parsing is isolated to the named migration boundary.
- Every registry key has owner/propagation/sensitivity/persistence/default-source/runtime-impact metadata and drift tests.
- V2 supports exact explicit-intent serialization and schema-derived redacted views; secret-bearing values never enter ordinary diagnostics/logs/manifests/telemetry.
- Qualified IDs, ambiguity, collision, traversal, reverse-reference, read-only source, etag, atomic CRUD, and trust behavior are tested cross-platform.
- A successful migration exposes one complete checksummed v2 generation and coordinated settings state; any corrupt profile or injected crash leaves a complete recoverable old state and preserves backups.
- Rollback is explicit and lock-protected; newer v2 edits are not silently reverse-converted.
- Full test/lint/typecheck/format/build verification passes for the affected packages.
Parent: #2635
Objective
Build the durable data foundation for transactional profiles: registry ownership/propagation metadata, typed
ProfileDocumentV2, qualified repository identity, schema-derived redaction, and an automatic all-or-nothing v1→v2 generation migration.This task is persistence/schema only. It does not introduce a second active-state owner, construct provider runtimes, or duplicate #2533's generic naming enforcement.
Scope
Registry taxonomy
emojifilter,dumpcontext,dumponerror, andui.showReasoningfrom profile persistence; add/wire application settings as required.reasoning.contextPolicydefaulting to preserve.compression-preserve-threshold, tool-format aliases/wire-format intent, and user context-limit versus catalog capacity.Profile v2
Define strict standard/LB schemas with:
provider.extensionsandmodel.extensionsonly;ProfileDocumentView/diff serializers.Repository identity and CRUD foundation
Migration/recovery
Implement a bounded
LegacyProfileMigrationSourceand generation/journal protocol:Support explicit read-only in-memory-v2 or strict-failure behavior. Fault-inject every staging/settings/pointer/completion boundary, concurrent startup, lock recovery, backup collision, and rollback. Normal repository consumers accept v2 only after durable activation. No automatic v1/v2 dual writes.
Coordination / non-overlap
Acceptance criteria