mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 21:41:09 +02:00
feat(crypto): Phase 2a — declare encryption intent for tags/scenes/missions
Preparation step for the space-scoped data model migration (Phase 2b).
Moves globalTags, tagGroups, workbenchScenes, and aiMissions from the
plaintext allowlist into the encryption registry with enabled:false —
so the audit script documents which fields WILL be encrypted without
changing any runtime behaviour.
Fields chosen per design-doc:
- globalTags.name — personal categorization (Therapie, Finanzen-privat)
- tagGroups.name — same
- workbenchScenes.name + description — scene labels often encode
Space-specific context (Q2-Launch, Urlaub 2026)
- aiMissions.title + conceptMarkdown + objective — all user-typed
mission config; state/cadence/inputs stay plaintext for the Runner
Deliberately kept plaintext (against my initial suggestion):
- aiAgents.name — registry comment explains: name is the Actor
displayName cache key for historic attribution. Encrypting would
show "🤖 [encrypted]" on every past task the agent ever touched.
- globalTags.icon / tagGroups.icon / color — not personal content;
icon is a visual cue, color is theme metadata
The 2c migration (Dexie v35, flip enabled:true) runs after 2b lands
the schema changes so existing rows get encrypted in one controlled
pass instead of mixing schema + encryption in the same upgrade.
Crypto audit: 195 Dexie tables classified (94 encrypted, 101
plaintext-allowlisted). Type-check clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3e09ff66d1
commit
766ad2ea8f
2 changed files with 36 additions and 4 deletions
|
|
@ -19,7 +19,6 @@
|
|||
export const PLAINTEXT_ALLOWLIST: readonly string[] = [
|
||||
'achievements', // TODO: audit
|
||||
'activities', // TODO: audit
|
||||
'aiMissions', // TODO: audit
|
||||
'albumItems', // TODO: audit
|
||||
'albums', // TODO: audit
|
||||
'articleTags', // FK-only junction into globalTags (articleId, tagId). Tag names live in globalTags.
|
||||
|
|
@ -50,7 +49,6 @@ export const PLAINTEXT_ALLOWLIST: readonly string[] = [
|
|||
'fileTags', // TODO: audit
|
||||
'financeCategories', // TODO: audit
|
||||
'foodFavorites', // TODO: audit
|
||||
'globalTags', // TODO: audit
|
||||
'goals', // TODO: audit
|
||||
'guideCollections', // TODO: audit
|
||||
'guideTags', // TODO: audit
|
||||
|
|
@ -99,7 +97,6 @@ export const PLAINTEXT_ALLOWLIST: readonly string[] = [
|
|||
'songTags', // TODO: audit
|
||||
'spaceMembers', // TODO: audit
|
||||
'storageFolders', // TODO: audit
|
||||
'tagGroups', // TODO: audit
|
||||
'taskLabels', // TODO: audit
|
||||
'timeAlarms', // TODO: audit
|
||||
'timeBlockTags', // TODO: audit
|
||||
|
|
@ -121,5 +118,4 @@ export const PLAINTEXT_ALLOWLIST: readonly string[] = [
|
|||
'wishesItems', // TODO: audit
|
||||
'wishesLists', // TODO: audit
|
||||
'wishesPriceChecks', // TODO: audit
|
||||
'workbenchScenes', // TODO: audit
|
||||
];
|
||||
|
|
|
|||
|
|
@ -573,6 +573,42 @@ export const ENCRYPTION_REGISTRY: Record<string, EncryptionConfig> = {
|
|||
// structural fields.
|
||||
agents: { enabled: true, fields: ['systemPrompt', 'memory'] },
|
||||
|
||||
// ─── AI Missions ─────────────────────────────────────────
|
||||
// docs/plans/space-scoped-data-model.md §2a — declared with
|
||||
// enabled:false during prep so the audit script is happy; flips to
|
||||
// true in 2c alongside the Dexie v35 encryption migration.
|
||||
//
|
||||
// User-typed content on missions: `title` (display label the user
|
||||
// types at create time), `conceptMarkdown` (free-form context the
|
||||
// planner reads), `objective` (the actionable goal string). State,
|
||||
// cadence, inputs (FK-only), nextRunAt, iterations, agentId all
|
||||
// stay plaintext — needed for the Runner's "due now" index walk
|
||||
// and mission-detail filters.
|
||||
aiMissions: { enabled: false, fields: ['title', 'conceptMarkdown', 'objective'] },
|
||||
|
||||
// ─── Tags (shared-stores) ────────────────────────────────
|
||||
// docs/plans/space-scoped-data-model.md §2a — declared with
|
||||
// enabled:false during prep; flips to true in 2c. Tag names like
|
||||
// "Therapie" or "Finanzen-privat" can leak personal categorization,
|
||||
// so they belong under encryption. `color` + `icon` + `groupId` +
|
||||
// `sortOrder` stay plaintext: they're visual metadata + the group
|
||||
// FK, none of which leak sensitive taxonomy. `name` is NOT indexed
|
||||
// for .where() lookups today, so encrypting it is safe — dedupe-
|
||||
// within-space lookups go through the new [spaceId+name] index after
|
||||
// Phase 2b and run over already-decrypted rows in the scoped store.
|
||||
globalTags: { enabled: false, fields: ['name'] },
|
||||
tagGroups: { enabled: false, fields: ['name'] },
|
||||
|
||||
// ─── Workbench Scenes ────────────────────────────────────
|
||||
// docs/plans/space-scoped-data-model.md §2a — declared with
|
||||
// enabled:false during prep; flips to true in 2c. `name` is the
|
||||
// user-visible scene label ("Heute", "Q2-Launch") and `description`
|
||||
// is the short subtitle — both are user-typed free text that can
|
||||
// leak Space-specific context. openApps / order / wallpaper /
|
||||
// viewingAsAgentId / scopeTagIds stay plaintext (structural /
|
||||
// indexed / foreign-key data).
|
||||
workbenchScenes: { enabled: false, fields: ['name', 'description'] },
|
||||
|
||||
// ─── Articles (Pocket-style read-it-later) ──────────────
|
||||
// Reading-behaviour data — same sensitivity class as newsArticles.
|
||||
// Encrypted:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue