Phase 3. Events are the append-only record of everything a mind does (ADR-0002). pkg/events defines the closed type vocabulary, categories, evidence references and the observation payload with explicit trust levels. The store validates and appends inside the caller's transaction, publishes to a bounded fan-out bus only after commit, queries by seq cursor with type/category/source/salience/confidence/time/search filters, and walks provenance: cause, parents, children, cited evidence, derived events and correlation groups. Durable per-consumer cursors never move backwards. Server-Sent Events streams (per mind and global) subscribe before replaying history after Last-Event-ID so nothing is missed, apply the same filter vocabulary live, and heartbeat. Operators can inject observations tagged with operator trust for demos and tests. UI: live thought stream with filters and paging, forensic event page with causal chain and evidence navigation, dashboard important events. Personality and status changes now leave operator_action events in the mind's own history. CLI: event inspect/list/tail, observe.
61 lines
3.7 KiB
HTML
61 lines
3.7 KiB
HTML
{{define "content"}}
|
|
{{$m := .Data.Mind}}
|
|
<div class="pagehead mindhead">
|
|
<div><h1>{{$m.DisplayName}} <span class="muted small">personality</span></h1><p class="muted">Version {{$m.PersonalityVersion}}{{if .Data.Template}} · based on template <strong>{{.Data.Template.Name}}</strong>{{end}}. Every save creates a new version; nothing is overwritten.</p></div>
|
|
<div class="row"><a class="btn small" href="/minds/{{$m.Slug}}/personality.json">Export JSON</a></div>
|
|
</div>
|
|
{{template "mind_tabs" (dict "M" $m "Active" "personality")}}
|
|
{{$admin := .Principal.User.Role.AtLeast "administrator"}}
|
|
<section class="grid cols-3-1">
|
|
<div>
|
|
<form method="post" action="/minds/{{$m.Slug}}/personality" class="card stack" id="pform">
|
|
<input type="hidden" name="_csrf" value="{{.CSRF}}">
|
|
{{template "personality_form" (dict "P" $m.Personality)}}
|
|
<div class="row">
|
|
<input name="change_note" placeholder="Change note (why)" maxlength="200" class="grow">
|
|
{{if $admin}}<button class="btn btn-primary" type="submit">Save as version {{inc $m.PersonalityVersion}}</button>{{end}}
|
|
<button class="btn" type="submit" formaction="/minds/{{$m.Slug}}/personality/preview" formmethod="post">Preview brief</button>
|
|
</div>
|
|
</form>
|
|
{{with .Data.Preview}}<div class="card highlight"><h2>Preview (unsaved)</h2><pre class="brief">{{.}}</pre></div>{{end}}
|
|
</div>
|
|
<div class="stack">
|
|
<div class="card">
|
|
<h2>Template</h2>
|
|
{{if $admin}}
|
|
<form method="post" action="/minds/{{$m.Slug}}/personality/template" class="stack">
|
|
<input type="hidden" name="_csrf" value="{{.CSRF}}">
|
|
<select name="template_id"><option value="">None (detach)</option>{{range .Data.Templates}}<option value="{{.ID}}" {{if and $.Data.Template (eq .ID $.Data.Template.ID)}}selected{{end}}>{{.Name}}</option>{{end}}</select>
|
|
<button class="btn small" type="submit">Apply template</button>
|
|
</form>
|
|
<p class="muted small">Mind-specific overrides are kept when a template is applied or re-applied.</p>
|
|
{{else}}<p class="muted small">{{if .Data.Template}}{{.Data.Template.Name}}{{else}}None{{end}}</p>{{end}}
|
|
{{if .Data.Overrides}}<h3>Overrides</h3><ul class="small mono">{{range $k, $v := .Data.Overrides}}<li>{{$k}}</li>{{end}}</ul>{{end}}
|
|
</div>
|
|
<div class="card">
|
|
<h2>History</h2>
|
|
<table class="table compact">
|
|
<thead><tr><th>v</th><th>Note</th><th>By</th><th></th></tr></thead>
|
|
<tbody>{{range .Data.Versions}}<tr>
|
|
<td>{{.Version}}{{if eq .Version $m.PersonalityVersion}} <span class="badge accent">current</span>{{end}}</td>
|
|
<td class="small">{{.ChangeNote}}<div class="muted">{{ago .CreatedAt}}</div></td>
|
|
<td class="small muted">{{.CreatedBy}}</td>
|
|
<td class="nowrap">{{if ne .Version $m.PersonalityVersion}}<a class="small" href="/minds/{{$m.Slug}}/personality/diff?a={{.Version}}&b={{$m.PersonalityVersion}}">diff</a>
|
|
{{if $admin}}<form method="post" action="/minds/{{$m.Slug}}/personality/versions/{{.Version}}/restore" class="inline"><input type="hidden" name="_csrf" value="{{$.CSRF}}"><button class="btn small" data-confirm="Restore version {{.Version}} as a new version?">restore</button></form>{{end}}{{end}}</td>
|
|
</tr>{{end}}</tbody>
|
|
</table>
|
|
</div>
|
|
{{if $admin}}
|
|
<div class="card">
|
|
<h2>Import JSON</h2>
|
|
<form method="post" action="/minds/{{$m.Slug}}/personality/import" class="stack">
|
|
<input type="hidden" name="_csrf" value="{{.CSRF}}">
|
|
<textarea name="json" rows="5" placeholder='{"identity":{...},"values":{...}}' required></textarea>
|
|
<button class="btn small" type="submit">Import as new version</button>
|
|
</form>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</section>
|
|
{{end}}
|