sonaloop 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. sonaloop-0.1.0/.gitignore +170 -0
  2. sonaloop-0.1.0/AGENTS.md +228 -0
  3. sonaloop-0.1.0/LICENSE +21 -0
  4. sonaloop-0.1.0/PKG-INFO +322 -0
  5. sonaloop-0.1.0/README.md +295 -0
  6. sonaloop-0.1.0/pyproject.toml +58 -0
  7. sonaloop-0.1.0/sonaloop/__init__.py +5 -0
  8. sonaloop-0.1.0/sonaloop/_icons.py +190 -0
  9. sonaloop-0.1.0/sonaloop/artifacts.py +392 -0
  10. sonaloop-0.1.0/sonaloop/assets.py +55 -0
  11. sonaloop-0.1.0/sonaloop/avatar.py +108 -0
  12. sonaloop-0.1.0/sonaloop/browser.py +251 -0
  13. sonaloop-0.1.0/sonaloop/cli.py +742 -0
  14. sonaloop-0.1.0/sonaloop/config.py +291 -0
  15. sonaloop-0.1.0/sonaloop/evaluation.py +346 -0
  16. sonaloop-0.1.0/sonaloop/llm_simulation/__init__.py +45 -0
  17. sonaloop-0.1.0/sonaloop/llm_simulation/_prompts.py +329 -0
  18. sonaloop-0.1.0/sonaloop/llm_simulation/_schemas.py +104 -0
  19. sonaloop-0.1.0/sonaloop/llm_simulation/_validators.py +371 -0
  20. sonaloop-0.1.0/sonaloop/mcp_server/__init__.py +56 -0
  21. sonaloop-0.1.0/sonaloop/mcp_server/_catalogue.py +90 -0
  22. sonaloop-0.1.0/sonaloop/mcp_server/_env.py +70 -0
  23. sonaloop-0.1.0/sonaloop/mcp_server/_tools_council.py +183 -0
  24. sonaloop-0.1.0/sonaloop/mcp_server/_tools_eval.py +159 -0
  25. sonaloop-0.1.0/sonaloop/mcp_server/_tools_methodology.py +81 -0
  26. sonaloop-0.1.0/sonaloop/mcp_server/_tools_personas.py +80 -0
  27. sonaloop-0.1.0/sonaloop/mcp_server/_tools_plan.py +142 -0
  28. sonaloop-0.1.0/sonaloop/mcp_server/_tools_prototypes.py +125 -0
  29. sonaloop-0.1.0/sonaloop/mcp_server/_tools_research.py +107 -0
  30. sonaloop-0.1.0/sonaloop/mcp_server/_tools_sections.py +138 -0
  31. sonaloop-0.1.0/sonaloop/mcp_server/_tools_simulation.py +203 -0
  32. sonaloop-0.1.0/sonaloop/memory.py +366 -0
  33. sonaloop-0.1.0/sonaloop/methodologies/double_diamond.json +35 -0
  34. sonaloop-0.1.0/sonaloop/methodologies/double_diamond_deep.json +48 -0
  35. sonaloop-0.1.0/sonaloop/methodologies/dschool_micro.json +35 -0
  36. sonaloop-0.1.0/sonaloop/methodologies/lean_jtbd.json +35 -0
  37. sonaloop-0.1.0/sonaloop/methodology.py +265 -0
  38. sonaloop-0.1.0/sonaloop/models.py +373 -0
  39. sonaloop-0.1.0/sonaloop/plan.py +757 -0
  40. sonaloop-0.1.0/sonaloop/plan_render.py +63 -0
  41. sonaloop-0.1.0/sonaloop/presentation.py +203 -0
  42. sonaloop-0.1.0/sonaloop/prototype_templates/spa-cards/index.html +83 -0
  43. sonaloop-0.1.0/sonaloop/prototype_templates/spa-comparison/index.html +84 -0
  44. sonaloop-0.1.0/sonaloop/prototype_templates/spa-dashboard/index.html +80 -0
  45. sonaloop-0.1.0/sonaloop/prototype_templates/spa-flow/index.html +90 -0
  46. sonaloop-0.1.0/sonaloop/prototype_templates/spa-hifi/index.html +69 -0
  47. sonaloop-0.1.0/sonaloop/prototype_templates/spa-journey/index.html +161 -0
  48. sonaloop-0.1.0/sonaloop/prototype_templates/spa-min/index.html +70 -0
  49. sonaloop-0.1.0/sonaloop/prototype_templates/spa-model/index.html +184 -0
  50. sonaloop-0.1.0/sonaloop/prototype_templates/spa-sketch/index.html +72 -0
  51. sonaloop-0.1.0/sonaloop/prototypes.py +255 -0
  52. sonaloop-0.1.0/sonaloop/services/__init__.py +197 -0
  53. sonaloop-0.1.0/sonaloop/services/_authoring.py +36 -0
  54. sonaloop-0.1.0/sonaloop/services/_common.py +210 -0
  55. sonaloop-0.1.0/sonaloop/services/_consolidation.py +345 -0
  56. sonaloop-0.1.0/sonaloop/services/_councils.py +322 -0
  57. sonaloop-0.1.0/sonaloop/services/_engines.py +649 -0
  58. sonaloop-0.1.0/sonaloop/services/_evaluation.py +452 -0
  59. sonaloop-0.1.0/sonaloop/services/_memory.py +217 -0
  60. sonaloop-0.1.0/sonaloop/services/_personas.py +647 -0
  61. sonaloop-0.1.0/sonaloop/services/_research.py +587 -0
  62. sonaloop-0.1.0/sonaloop/services/_sections.py +300 -0
  63. sonaloop-0.1.0/sonaloop/services/_simulation.py +670 -0
  64. sonaloop-0.1.0/sonaloop/services/_snapshots.py +231 -0
  65. sonaloop-0.1.0/sonaloop/services/_synthesis.py +521 -0
  66. sonaloop-0.1.0/sonaloop/storage/__init__.py +31 -0
  67. sonaloop-0.1.0/sonaloop/storage/_base.py +141 -0
  68. sonaloop-0.1.0/sonaloop/storage/_councils.py +60 -0
  69. sonaloop-0.1.0/sonaloop/storage/_memory.py +242 -0
  70. sonaloop-0.1.0/sonaloop/storage/_personas.py +50 -0
  71. sonaloop-0.1.0/sonaloop/storage/_prototypes.py +55 -0
  72. sonaloop-0.1.0/sonaloop/storage/_research.py +187 -0
  73. sonaloop-0.1.0/sonaloop/storage/_schema.py +321 -0
  74. sonaloop-0.1.0/sonaloop/storage/_simulation.py +103 -0
  75. sonaloop-0.1.0/sonaloop/suggestions/artifact_types.json +68 -0
  76. sonaloop-0.1.0/sonaloop/suggestions/capabilities.json +12 -0
  77. sonaloop-0.1.0/sonaloop/suggestions/critic_rubric.json +20 -0
  78. sonaloop-0.1.0/sonaloop/suggestions/edge_types.json +13 -0
  79. sonaloop-0.1.0/sonaloop/suggestions/evidence_kinds.json +11 -0
  80. sonaloop-0.1.0/sonaloop/suggestions/finding_kinds.json +16 -0
  81. sonaloop-0.1.0/sonaloop/suggestions/ideation_lenses.json +22 -0
  82. sonaloop-0.1.0/sonaloop/suggestions/roles.json +13 -0
  83. sonaloop-0.1.0/sonaloop/suggestions/section_kinds.json +11 -0
  84. sonaloop-0.1.0/sonaloop/suggestions/stance_scale.json +18 -0
  85. sonaloop-0.1.0/sonaloop/suggestions.py +67 -0
  86. sonaloop-0.1.0/sonaloop/taxonomy.py +68 -0
  87. sonaloop-0.1.0/sonaloop/web/__init__.py +114 -0
  88. sonaloop-0.1.0/sonaloop/web/_components.py +792 -0
  89. sonaloop-0.1.0/sonaloop/web/_detail.py +107 -0
  90. sonaloop-0.1.0/sonaloop/web/_ext.py +180 -0
  91. sonaloop-0.1.0/sonaloop/web/_graph.py +790 -0
  92. sonaloop-0.1.0/sonaloop/web/_html.py +95 -0
  93. sonaloop-0.1.0/sonaloop/web/_i18n.py +350 -0
  94. sonaloop-0.1.0/sonaloop/web/_nav_seed.py +36 -0
  95. sonaloop-0.1.0/sonaloop/web/_palette.py +116 -0
  96. sonaloop-0.1.0/sonaloop/web/_rail.py +44 -0
  97. sonaloop-0.1.0/sonaloop/web/_render.py +209 -0
  98. sonaloop-0.1.0/sonaloop/web/_report.py +251 -0
  99. sonaloop-0.1.0/sonaloop/web/_routes_api.py +125 -0
  100. sonaloop-0.1.0/sonaloop/web/_routes_lists.py +314 -0
  101. sonaloop-0.1.0/sonaloop/web/_synthesis.py +434 -0
  102. sonaloop-0.1.0/sonaloop/web/_vm.py +32 -0
  103. sonaloop-0.1.0/sonaloop/web/pages/__init__.py +22 -0
  104. sonaloop-0.1.0/sonaloop/web/pages/_calendar.py +235 -0
  105. sonaloop-0.1.0/sonaloop/web/pages/_ctx.py +34 -0
  106. sonaloop-0.1.0/sonaloop/web/pages/councils.py +103 -0
  107. sonaloop-0.1.0/sonaloop/web/pages/library.py +114 -0
  108. sonaloop-0.1.0/sonaloop/web/pages/personas.py +227 -0
  109. sonaloop-0.1.0/sonaloop/web/pages/projects.py +188 -0
  110. sonaloop-0.1.0/sonaloop/web/pages/syntheses.py +90 -0
  111. sonaloop-0.1.0/sonaloop/web_assets.py +598 -0
@@ -0,0 +1,170 @@
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ lerna-debug.log*
8
+
9
+ # Diagnostic reports (https://nodejs.org/api/report.html)
10
+ report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
11
+
12
+ # Runtime data
13
+ pids
14
+ *.pid
15
+ *.seed
16
+ *.pid.lock
17
+
18
+ # Directory for instrumented libs generated by jscoverage/JSCover
19
+ lib-cov
20
+
21
+ # Coverage directory used by tools like istanbul
22
+ coverage
23
+ *.lcov
24
+
25
+ # nyc test coverage
26
+ .nyc_output
27
+
28
+ # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
29
+ .grunt
30
+
31
+ # Bower dependency directory (https://bower.io/)
32
+ bower_components
33
+
34
+ # node-waf configuration
35
+ .lock-wscript
36
+
37
+ # Compiled binary addons (https://nodejs.org/api/addons.html)
38
+ build/Release
39
+
40
+ # Dependency directories
41
+ node_modules/
42
+ jspm_packages/
43
+
44
+ # Snowpack dependency directory (https://snowpack.dev/)
45
+ web_modules/
46
+
47
+ # TypeScript cache
48
+ *.tsbuildinfo
49
+
50
+ # Optional npm cache directory
51
+ .npm
52
+
53
+ # Optional eslint cache
54
+ .eslintcache
55
+
56
+ # Optional stylelint cache
57
+ .stylelintcache
58
+
59
+ # Optional REPL history
60
+ .node_repl_history
61
+
62
+ # Output of 'npm pack'
63
+ *.tgz
64
+
65
+ # Yarn Integrity file
66
+ .yarn-integrity
67
+
68
+ # dotenv environment variable files
69
+ .env
70
+ .env.*
71
+ !.env.example
72
+
73
+ # Python
74
+ .venv/
75
+ __pycache__/
76
+ *.py[cod]
77
+
78
+ # Sonaloop state & private content. ALL of this is local-only and is
79
+ # NEVER committed — it can contain your real personas, councils and syntheses.
80
+ # Everything here is either volatile runtime or fully rebuildable, so excluding
81
+ # it keeps the public repo a clean, reusable engine with no private data.
82
+ data/sonaloop.db
83
+ data/sonaloop.db-shm
84
+ data/sonaloop.db-wal
85
+ # Local UI/content language choice (auto-detected per user) — local-only.
86
+ data/settings.json
87
+ data/avatars/
88
+ data/personas/
89
+ # Export snapshot (your personas / councils / syntheses) — keep private.
90
+ data/export/
91
+ # Canonical persona source prompts — your own profiles; keep private.
92
+ spec/persona-source-prompts.md
93
+ # Rendered synthesis reports (markdown / PDF) — keep private.
94
+ exports/
95
+ # Local Claude Code skill symlinks (created by `make skills`) — not committed;
96
+ # the real skills live in claude-skills/.
97
+ .claude/
98
+
99
+ # parcel-bundler cache (https://parceljs.org/)
100
+ .cache
101
+ .parcel-cache
102
+
103
+ # Next.js build output
104
+ .next
105
+ out
106
+
107
+ # Nuxt.js build / generate output
108
+ .nuxt
109
+ dist
110
+ .output
111
+
112
+ # Gatsby files
113
+ .cache/
114
+ # Comment in the public line in if your project uses Gatsby and not Next.js
115
+ # https://nextjs.org/blog/next-9-1#public-directory-support
116
+ # public
117
+
118
+ # vuepress build output
119
+ .vuepress/dist
120
+
121
+ # vuepress v2.x temp directory
122
+ .temp
123
+
124
+ # Sveltekit cache directory
125
+ .svelte-kit/
126
+
127
+ # vitepress build output
128
+ **/.vitepress/dist
129
+
130
+ # vitepress cache directory
131
+ **/.vitepress/cache
132
+
133
+ # Docusaurus cache and generated files
134
+ .docusaurus
135
+
136
+ # Serverless directories
137
+ .serverless/
138
+
139
+ # FuseBox cache
140
+ .fusebox/
141
+
142
+ # DynamoDB Local files
143
+ .dynamodb/
144
+
145
+ # Firebase cache directory
146
+ .firebase/
147
+
148
+ # TernJS port file
149
+ .tern-port
150
+
151
+ # Stores VSCode versions used for testing VSCode extensions
152
+ .vscode-test
153
+
154
+ # pnpm
155
+ .pnpm-store
156
+
157
+ # yarn v3
158
+ .pnp.*
159
+ .yarn/*
160
+ !.yarn/patches
161
+ !.yarn/plugins
162
+ !.yarn/releases
163
+ !.yarn/sdks
164
+ !.yarn/versions
165
+
166
+ # Vite files
167
+ vite.config.js.timestamp-*
168
+ vite.config.ts.timestamp-*
169
+ .vite/
170
+ data/assets/
@@ -0,0 +1,228 @@
1
+ # Sonaloop Agent Guide
2
+
3
+ Sonaloop is terminal-first and MCP-first. The web UI is an inspection
4
+ surface only.
5
+
6
+ ## Principles
7
+
8
+ - Do not infer product interest from the repository name, app name, or the fact
9
+ that this is a council tool.
10
+ - Do not steer profiles toward AI, automation, or any other product thesis
11
+ unless the profile source description, attached evidence, recent calendar, or
12
+ explicit task context supports it.
13
+ - Treat synthetic details as hypotheses. Prefer ordinary work, skepticism,
14
+ indifference, satisfaction, and rejection when those are plausible.
15
+ - Before speaking from a profile perspective, load `SOUL.md` through
16
+ `prepare_persona_agent_context` or `sonaloop persona-context`.
17
+ - Use CLI/MCP for all mutations: create profiles, generate avatars, simulate
18
+ days, attach evidence, run councils, clear simulations, and export logs.
19
+ - Point the user to the web inspector as soon as there is something to see. Once
20
+ personas/councils/syntheses exist, tell them to open **http://127.0.0.1:8787**
21
+ (start it with `make dev`, or `sonaloop-web`, which prints the URL). The
22
+ web UI is read-only; all authoring still happens through CLI/MCP.
23
+ - Language: generated CONTENT follows the language the user writes in, auto-
24
+ detected on first input and persisted (de|en). Do not switch languages
25
+ mid-stream. The web UI language is independent (toggle in the top bar, or
26
+ `set_language`/`set-language`). Override content language only if asked.
27
+
28
+ ## CLI
29
+
30
+ ```bash
31
+ # Persona creation is host-authored (no server-side text generation):
32
+ # gather -> you author the profile JSON -> persist.
33
+ sonaloop brief-persona "Restaurantleiterin in Deutschland, mittelgroßes Team, plant Schichten, Lieferanten, Reklamationen und Tagesabschluss, nutzt Kassensystem, Dienstplan, E-Mail und Telefon."
34
+ sonaloop record-persona profile.json # JSON: {description, profile, segment_hint?, evidence?, generate_avatar?}
35
+ sonaloop persona-list
36
+ sonaloop persona-get <persona-id-or-slug>
37
+ sonaloop persona-soul <persona-id-or-slug>
38
+ sonaloop persona-context <persona-id-or-slug> --task "Evaluate this idea neutrally" --text
39
+ sonaloop avatar-generate <persona-id-or-slug>
40
+
41
+ # Single day, host-authored: brief-day -> author {day_plan, plan, activities} -> record-day.
42
+ sonaloop brief-day <persona-id-or-slug> --date 2026-06-02
43
+ sonaloop record-day <persona-id-or-slug> 2026-06-02 day.json
44
+ sonaloop simulate-continue --all --days 1
45
+ sonaloop simulate-clear
46
+ sonaloop purge-runtime-data
47
+
48
+ sonaloop calendar <persona-id-or-slug> --date 2026-06-02 --view day
49
+ sonaloop calendar <persona-id-or-slug> --date 2026-06-02 --view week
50
+ sonaloop activity <activity-id>
51
+ sonaloop state <persona-id-or-slug>
52
+ sonaloop summary <persona-id-or-slug> --start 2026-06-01 --end 2026-06-30
53
+
54
+ # Councils & interviews are host-authored (see the run-council skill):
55
+ # brief-council <prompt> -> candidate personas to choose from
56
+ # brief-council <prompt> --persona <id>… -> each participant's loaded context
57
+ # (author turns + synthesis) -> record-council council.json
58
+ sonaloop brief-council "Should we change the approval workflow?" --persona <id> --persona <id>
59
+ sonaloop brief-ask <persona-id-or-slug> "What would make this unacceptable in your week?"
60
+
61
+ # Language: content is auto-detected from what you write, then persisted (de|en).
62
+ sonaloop language
63
+ sonaloop set-language --content de --ui en
64
+
65
+ sonaloop evidence-attach <persona-id-or-slug> interview notes/interview-01.md --notes "Customer interview"
66
+ sonaloop export-logs <persona-id-or-slug> --format md --out exports/logs.md
67
+ sonaloop export-council <session-id> --format md --out exports/council.md
68
+ ```
69
+
70
+ ## MCP
71
+
72
+ Run:
73
+
74
+ ```bash
75
+ sonaloop-mcp
76
+ ```
77
+
78
+ Core MCP tools:
79
+
80
+ - `brief_persona` (gather) → `record_persona` (persist authored profile), `update_persona`
81
+ - `get_persona`, `list_personas`, `get_persona_soul`
82
+ - `prepare_persona_agent_context`
83
+ - `generate_avatar`
84
+ - `brief_day` → `record_day` (host-authored single day); `record_month_bundle` for
85
+ months; `continue_simulation`, `clear_simulations`, `purge_runtime_data`
86
+ - `get_current_state`, `get_calendar`, `get_calendar_period`, `get_activity`
87
+ - `summarize_persona_period`, `extract_pain_points`
88
+ - `brief_council` (gather candidates/contexts) → `record_council` (persist authored
89
+ turns + synthesis), `get_council`, `list_councils`, `brief_ask`
90
+ - `get_language`, `set_language` (UI + generated-content language, de|en)
91
+ - `attach_evidence`
92
+ - `export_persona`, `export_logs`, `export_council_session`
93
+
94
+ Memory & multi-resolution simulation (gather → author → write-back):
95
+
96
+ - Planning: `brief_day`/`put_day_plan`/`get_day_plan`,
97
+ `brief_period`/`put_period_plan`/`get_period_plan`/`list_period_plans`
98
+ - Consolidation: `brief_consolidation`/`record_memory_deltas`
99
+ - Digests: `brief_digest`/`put_digest`/`list_digests`
100
+ - Retrieval/inspection: `recall_memory` (hybrid: keyword + OpenAI embeddings),
101
+ `list_active_projects`, `get_project`, `get_state_at` (time-travel),
102
+ `get_timeline`, `search_entities`, `get_open_loops`, `resolve_entity`,
103
+ `get_persona_memory`
104
+ - World/evolution/quality: `set_world_context`/`get_world_context`,
105
+ `brief_persona_revision`/`record_persona_revision`/`list_persona_revisions`,
106
+ `evaluate_simulation`, `brief_eval_critic`/`record_eval_critic`/
107
+ `evaluate_simulation_full`, `list_memory_anomalies`, `backfill_embeddings`,
108
+ `prune_memory`
109
+ - Driver: `brief_month`/`record_month_bundle`
110
+ - Synthesis (study arc over a council chain = an **analysis**: question → council
111
+ loop → synthesis report): `brief_synthesis`/`record_synthesis`/`get_synthesis`/
112
+ `list_syntheses`/`export_synthesis`. `brief_synthesis` returns per-persona turns +
113
+ votes per council; author the structured **`voices`** array in the payload (one per
114
+ persona: `sentiment`, `relevance`/tangiert, `key_argument`, `shift`{from,to,trigger,
115
+ council_id}, `evidence`[{council_id,quote}]) — this powers the report's filterable
116
+ Stimmen panel and the self-contained `export_synthesis` (md/json) for downstream agents.
117
+ - Portability: `export_snapshot`/`import_snapshot` (data/export is the one
118
+ portable artifact; it is gitignored/local-only, as is the SQLite DB runtime)
119
+ - Research-plan engine — the SINGLE runtime engine (structure-enforcing + LLM-judged; ZERO hardcoded
120
+ vocabularies): a per-project DAG of analyze→act→verify **tasks**, each bound to a free `capability`
121
+ and referencing the evidence it produced. `start_project` (freeform: one root `frame` task; or
122
+ `methodology=…`: seed the constellation), then the per-iteration loop `next_action`/`brief_next` →
123
+ author the step → `add_task`/`record_frame`/`link_evidence`/`record_judgment`(free `gate_tag`) →
124
+ `complete_task`, with `assess_project`/`assess_progress` for the read-only meta-assessment.
125
+ Tag-agnostic: it enforces only the DAG (`consumes`), integer `min_inputs`, tag-equality references,
126
+ and evidence-backed judgment PRESENCE — never tag membership. Shape (diverge/converge/diamonds/
127
+ branches/loops) is DERIVED from the task DAG + recorded evidence.
128
+ - ESV — exhaustive, self-verifying runs (`spec/exhaustive-self-verifying-runs.md`). The autonomous loop
129
+ is a **deterministic RunLoop engine** the host skill executes: `start_run`(resumable run object +
130
+ journal) → loop `run_step` (the brain: assess + next_action + the deterministic finish work + the
131
+ critic gate) → spawn ONE subagent per dispatch → `checkpoint_step`. "Done" ≠ "gates passed": a run is
132
+ only `complete` when `assess_project.finish` is **finished** (organized via `derive_sections` +
133
+ concluded + handed-off via `scaffold_meta_report`/meta-report) AND an INDEPENDENT
134
+ **completeness critic** (`brief_completeness_critic`→`record_completeness_critic`, rubric in
135
+ `suggestions/critic_rubric.json`) passes — it lists concrete `missing` work (un-sampled segments,
136
+ un-prototyped concepts, untested risks, missing fidelity rungs), the driver injects each as real work
137
+ (`inject_work`) and re-runs until dry (K=2, hard cap 4). `assess_project` also surfaces `novelty`,
138
+ `memory_depth` (thin cohorts → deepen via simulate-cohort), and `score_run` tracks quality over time.
139
+ Concepts are first-class (`create_note kind="concept"` {lens, artifact_kind, prototype_id}). Resumable
140
+ via deterministic keys; a killed run replays its journal with zero lost work.
141
+ - Methodologies = tag-driven CONSTELLATION **plan seeds**: a methodology is a DAG of steps carrying
142
+ OPEN TAGS (capability/role/artifact-type/gate are free strings). `list_methodologies`/
143
+ `get_methodology`/`start_methodology_project`/`set_project_methodology` SEED a plan from the
144
+ constellation (a `frame` analyze task per fan step, a gated `verify` task per decide step); the plan
145
+ engine then drives it. Common building blocks are SUGGESTED as data via `suggest_capabilities`/
146
+ `suggest_roles`/`suggest_artifact_types`/`suggest_methodologies` — recommendations, not constraints;
147
+ adopt, tweak, or invent your own tags. Authoring a new methodology = author a constellation of
148
+ tagged steps in JSON (no code). Since HX3 there is ONE engine (the plan); the old constellation
149
+ runtime (`record_node`/`record_decision`/`advance`/`get_methodology_state`) was retired — see
150
+ `spec/hx3-engine-collapse.md`. Specs: `spec/methodology-constellations.md`, `spec/research-plan-engine.md`.
151
+ - Prototypes (real, minimal, local apps agents can use): `scaffold_prototype` (concept→clickable
152
+ SPA), `register_prototype`, `list_prototypes`, `run_prototype`/`stop_prototype`; the Playwright
153
+ harness `proto_open`/`proto_act`/`proto_read`/`proto_close` lets a persona drive the REAL app,
154
+ and `brief_prototype_session`/`record_prototype_session` fold the grounded reaction into memory.
155
+ Artifact archetypes are DATA (`suggestions/artifact_types.json`, surfaced as the `artifact_palette`
156
+ in `next_action`): a guided `flow`, a `comparison`, a `dashboard`, a `cards` interface, or an
157
+ interactive **`model`** (range/number inputs feeding `computed`/`bar` elements whose `formula` is
158
+ evaluated live — a steerable pension-gap/compounding simulation, not a static screen), or a
159
+ **`journey`** (a model embedded in a multi-screen flow with cross-screen state + `chart` live curves
160
+ + `verdict` data-driven conditional text — the production-credible hi-fi class) — diversify the KIND,
161
+ don't default to a form. `record_prototype_session` returns an `UNVERIFIED_SESSION`
162
+ warning (and a session_of_tags gate requires a GROUNDED session) when a reaction isn't verified
163
+ against real observed usage — the session log is retained past `proto_close` so a real drive verifies.
164
+ Install with `make playwright` (optional; degrades gracefully without chromium).
165
+ - Composable graph — the graph is a canvas of composable LOW-LEVEL primitives (council · synthesis ·
166
+ prototype · **note** · edge · **section**); the methodology/plan engine is ONE optional orchestrator,
167
+ not the only structure (spec/sections-and-composable-graph.md):
168
+ - **Sections** = methodology-INDEPENDENT labeled overlay groupings of nodes ("Initial user research",
169
+ "Problem exploration"). Explicit set-membership (overlap allowed), a pure overlay (never alters the
170
+ DAG layout), reference-not-containment (deleting a section never deletes nodes), `kind` an open tag
171
+ (theme/phase/invented, data-driven via `section_kinds.json`). `create_section`/`update_section`/
172
+ `add_to_section`/`remove_from_section`/`set_section_members` (promote-a-cluster)/`reorder_sections`/
173
+ `list_sections`/`get_section`/`delete_section`/`get_section_members`/`export_section` (md/json,
174
+ self-contained) + `suggest_section_kinds`. Methodology phases render as DERIVED `phase` sections.
175
+ - **Notes** = lightweight first-class observation nodes (the atomic unit for affinity), creatable with
176
+ NO methodology: `create_note`/`list_notes`/`delete_note`. They are normal graph nodes (groupable
177
+ into sections, linkable by edges).
178
+ - **Syntheses are DECOUPLED from councils**: a synthesis can have zero councils (affinity over notes,
179
+ a synthesis over other syntheses, a standalone analysis); councils are cited, not owned.
180
+
181
+ Every tool returns an envelope `{ok, data, next_recommended_tool, _meta}`; the
182
+ `next_recommended_tool` hints the decision DAG (simulate → consolidate → digest;
183
+ council → synthesis). Full surface + conventions: `spec/mcp-tool-contract.md`.
184
+
185
+ ## Skills (Claude Code)
186
+
187
+ Run `make skills` once (symlinks `claude-skills/*` into gitignored
188
+ `.claude/skills/`). Skills are thin orchestration playbooks; the methodology
189
+ lives in `spec/`.
190
+
191
+ - `methodology-run` — drive a plan-based methodology constellation (Double Diamond, d.school
192
+ micro-cycle, Lean/JTBD, … or any you author) over the graph via the analyze→act→verify plan loop:
193
+ genuinely fan out act tasks (real councils / built+tested prototypes) then converge behind an
194
+ evidence-backed gate (`record_judgment` + a `record_synthesis`), incl. build/test steps where
195
+ personas USE a real app via Playwright. The plan engine enforces the shape; you author the text.
196
+ Specs: `methodology-constellations.md`, `research-plan-engine.md`.
197
+ - `simulate-cohort` — run the day/period loop for personas over months (sampling).
198
+ - `run-council` — memory-grounded council; judicious self-research (recall only
199
+ when it sharpens the answer); optional moderated back-and-forth with mediator
200
+ strategies (`positive-deepdive`, `pain-discovery`, `tension`, `goal`) and a
201
+ hand-raising convergence loop + upper bound.
202
+ - `synthesize` — iterative driver: one statement → councils → read each exec
203
+ summary → decide a follow-up (self-contained question, personas are
204
+ council-stateless) or stop (goal reached / no follow-up / max 10) → report.
205
+
206
+ ## Persona-Subagent Workflow
207
+
208
+ 1. Call `prepare_persona_agent_context(persona_id, task, recent_events)`.
209
+ 2. Verify `soul_loaded=true`.
210
+ 3. Use the returned `agent_context` as the launch context for the subagent.
211
+ 4. Ground responses in the loaded SOUL, recent events, evidence, and task.
212
+ 5. If the context does not support a product-friendly answer, the profile should
213
+ be skeptical, neutral, or rejecting.
214
+
215
+ ## Simulation Quality
216
+
217
+ - Good simulations include timestamped activities, concrete tools/artifacts,
218
+ realistic conversations, internal thoughts, decisions, unresolved loops, and
219
+ emotional/energy shifts.
220
+ - Persona answers and council turns are LLM-authored through MCP/service calls;
221
+ they must load `SOUL.md` via `prepare_persona_agent_context`.
222
+ - Council selection is LLM-authored from candidate persona summaries. Do not
223
+ choose participants with fixed keyword scoring or product-topic assumptions.
224
+ - A meeting should contain enough conversation to understand what happened, not
225
+ just one summary quote.
226
+ - A workday should include mundane friction and normal progress, not only
227
+ problems.
228
+ - Calendar continuity matters: unresolved loops should influence later days.
sonaloop-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Johannes Hötter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.