@unson/brainbase-mcp 0.41.6 → 0.41.8

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.
@@ -78,9 +78,13 @@ export interface FoundationObjectiveDetails {
78
78
  readonly evaluator_note?: unknown;
79
79
  readonly current_state?: unknown;
80
80
  }
81
- /** Runtime shape used by the overview contract for Objective records. */
81
+ /** The words a World Model record gives for where it applies. */
82
+ export interface FoundationModelDetails {
83
+ readonly applicability_text?: unknown;
84
+ }
85
+ /** Runtime shape used by the overview contract for Objective and World Model records. */
82
86
  export interface FoundationOverviewObjectiveRecord extends FoundationCatalogRecord {
83
- readonly details?: FoundationObjectiveDetails;
87
+ readonly details?: FoundationObjectiveDetails | FoundationModelDetails;
84
88
  }
85
89
  export interface GraphFoundationReaders {
86
90
  readonly store: Pick<FoundationRevisionStore, 'read' | 'readLatest' | 'list'>;
@@ -525,12 +525,10 @@ function validateFoundationRecord(row, reference, context, selectedProjectCode,
525
525
  definition: cloneFoundationDefinition(history.definition),
526
526
  digest: digestFoundationDefinition(history.definition)
527
527
  };
528
- if (reference.type === 'objective') {
529
- const details = projectObjectiveDetails(history.payload);
530
- if (details !== undefined)
531
- return { ...record, details };
532
- }
533
- return record;
528
+ const details = reference.type === 'objective'
529
+ ? projectDetails(history.payload, OBJECTIVE_DETAIL_KEYS)
530
+ : reference.type === 'model' ? projectDetails(history.payload, MODEL_DETAIL_KEYS) : undefined;
531
+ return details === undefined ? record : { ...record, details };
534
532
  }
535
533
  const OBJECTIVE_DETAIL_KEYS = [
536
534
  'title',
@@ -540,15 +538,18 @@ const OBJECTIVE_DETAIL_KEYS = [
540
538
  'evaluator_note',
541
539
  'current_state'
542
540
  ];
543
- function projectObjectiveDetails(payload) {
541
+ // A model's foundation scope carries ids and a registration time; its own words for where it
542
+ // applies live beside the definition.
543
+ const MODEL_DETAIL_KEYS = ['applicability_text'];
544
+ function projectDetails(payload, keys) {
544
545
  const nestedDetails = isPlainRecord(payload.details) ? payload.details : undefined;
545
546
  const foundation = isPlainRecord(payload.foundation) ? payload.foundation : undefined;
546
547
  // Graphify payloads historically carried these descriptive fields at the
547
548
  // payload root. Keep the two known nested forms compatible while exposing
548
- // only the six fields in the overview contract.
549
+ // only the listed fields in the overview contract.
549
550
  const candidates = [payload, nestedDetails, foundation].filter((candidate) => candidate !== undefined);
550
551
  const projected = {};
551
- for (const key of OBJECTIVE_DETAIL_KEYS) {
552
+ for (const key of keys) {
552
553
  const source = candidates.find((candidate) => Object.prototype.hasOwnProperty.call(candidate, key));
553
554
  if (source !== undefined && source[key] !== undefined)
554
555
  projected[key] = source[key];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unson/brainbase-mcp",
3
- "version": "0.41.6",
3
+ "version": "0.41.8",
4
4
  "description": "Local-first Brainbase judgment OS that lets supported AI agents reuse a user's approved goals, priorities, decisions, and judgment criteria.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -483,5 +483,5 @@
483
483
  "engines": {
484
484
  "node": ">=20"
485
485
  },
486
- "gitHead": "0c67baf7d7c57f4f671c966c8053705af65ba4d0"
486
+ "gitHead": "b061e1b0a7ccb22155c6e22459ad735dc5e7adb1"
487
487
  }
@@ -26,6 +26,8 @@
26
26
  --bb-color-accent: #5b4bd8;
27
27
  --bb-color-accent-soft: #efedff;
28
28
  --bb-color-accent-strong: #4939b8;
29
+ /* Minutes screen remaps its accent to this indigo. Shared accent stays purple. */
30
+ --bb-color-brand-indigo: #0F2A43;
29
31
  --bb-color-action: #5b4bd8;
30
32
  --bb-color-action-hover: #4939b8;
31
33
  --bb-color-action-text: #ffffff;
@@ -151,14 +151,6 @@
151
151
  line-height: 1.55;
152
152
  }
153
153
 
154
- .bb-fov-record-id {
155
- display: block;
156
- margin-top: 7px;
157
- color: var(--bb-color-quiet);
158
- font-family: var(--bb-font-mono);
159
- font-size: 10px;
160
- overflow-wrap: anywhere;
161
- }
162
154
 
163
155
  .bb-fov-ref-list {
164
156
  display: grid;
@@ -254,4 +246,5 @@
254
246
  @media (max-width: 760px) { .bb-fov-objective-ledger { overflow-x: auto; } .bb-fov-objective-ledger .bb-ws-ledger-row { min-width: 760px; } }
255
247
  @media (max-width: 480px) { .bb-fov-reading .bb-ws-definition { grid-template-columns: 1fr; gap: 4px; } .bb-fov-reading dd { margin-bottom: 12px; } }
256
248
  .bb-fov-philosophy-card .bb-fov-original { border-top: 0; padding-top: 0; }
249
+ .bb-fov-model-card .bb-fov-original { margin-top: 12px; padding-top: 10px; overflow-wrap: anywhere; }
257
250
  .bb-fov-objective-ledger .bb-ws-ledger-row:focus-visible { outline: 2px solid var(--bb-color-focus); outline-offset: 2px; }
@@ -55,6 +55,16 @@ const PHILOSOPHY_STATUS_LABELS = Object.freeze({
55
55
  archived: '終了',
56
56
  });
57
57
  const OPERATOR_LABELS = Object.freeze({ at_least: '以上', at_most: '以下', equals: '一致' });
58
+ const SOURCE_KIND_LABELS = Object.freeze({
59
+ candidate: '候補からの登録',
60
+ document: '文書',
61
+ observation: '観察',
62
+ decision: '決定',
63
+ import: '取り込み',
64
+ });
65
+ // A record without a name is said to have none; its id stays in the record details (P9).
66
+ const UNNAMED_RECORD = '名前の記録なし';
67
+ const UNNAMED_VARIABLE = '名前の記録がない変数';
58
68
 
59
69
  export class FoundationOverviewError extends Error {
60
70
  constructor(code, message) {
@@ -225,12 +235,52 @@ const SCOPE_LABELS = Object.freeze({
225
235
  company: '組織',
226
236
  });
227
237
 
238
+ function formatValidity(from, until) {
239
+ if (!from && !until) return null;
240
+ if (!from) return `${formatDate(until)} まで`;
241
+ return `${formatDate(from)} から ${until ? `${formatDate(until)} まで` : '(終了日の記録なし)'}`;
242
+ }
243
+
244
+ /**
245
+ * A scope in words: `{ type, id }` names the project or organization, and a validity scope
246
+ * (`subjectIds`, `validFrom`, `validUntil`) becomes its period and the number of subjects. The
247
+ * subject ids themselves belong to the record details.
248
+ */
228
249
  function formatScope(value) {
229
250
  if (!isObject(value)) return formatStructuredValue(value);
230
251
  const type = formatAny(value.type);
231
252
  const id = formatAny(value.id);
232
253
  if (type && id) return `${SCOPE_LABELS[type] ?? type}: ${id}`;
233
- return formatStructuredValue(value);
254
+ const subjects = firstValue(value, 'subjectIds', 'subject_ids');
255
+ const period = formatValidity(firstValue(value, 'validFrom', 'valid_from'), firstValue(value, 'validUntil', 'valid_until'));
256
+ const parts = [
257
+ Array.isArray(subjects) && subjects.length > 0 ? `対象 ${subjects.length}件` : null,
258
+ period ? `適用期間: ${period}` : null,
259
+ ].filter(Boolean);
260
+ if (parts.length > 0) return parts.join(' / ');
261
+ return formatAny(firstValue(value, 'text', 'description', 'statement', 'label', 'name'))
262
+ ?? '読める形の記録がありません(記録の詳細を参照)';
263
+ }
264
+
265
+ /** Where a definition came from, as kinds of source; the source and evidence ids stay in the details. */
266
+ function formatProvenance(provenance) {
267
+ if (!Array.isArray(provenance) || provenance.length === 0) return null;
268
+ return provenance.map((item) => {
269
+ const kind = SOURCE_KIND_LABELS[item?.sourceKind] ?? '種類の記録なし';
270
+ const evidence = Array.isArray(item?.evidenceIds) ? item.evidenceIds.length : 0;
271
+ return evidence > 0 ? `${kind}(証拠${evidence}件)` : kind;
272
+ }).join('、');
273
+ }
274
+
275
+ /** Ids, revisions and digests of one record, for the "記録の詳細" disclosure only. */
276
+ function recordDetailsElement(doc, rows, summary = '記録の詳細') {
277
+ const details = makeElement(doc, 'details', { className: 'bb-fov-original' });
278
+ details.append(makeElement(doc, 'summary', { text: summary }), workspaceDefinition(doc, rows));
279
+ return details;
280
+ }
281
+
282
+ function referenceLabels(refs) {
283
+ return Array.isArray(refs) && refs.length > 0 ? refs.map(referenceLabel).join('、') : null;
234
284
  }
235
285
 
236
286
  function recordDefinition(record) { return isObject(record?.definition) ? record.definition : {}; }
@@ -265,6 +315,15 @@ function statusElement(doc, definition, className = '') {
265
315
  return makeElement(doc, 'p', { className: `bb-fov-status${className ? ` ${className}` : ''}`, text: statusText(definition) });
266
316
  }
267
317
 
318
+ /**
319
+ * The one state a reader needs in front of a model: whether it is held as verified or as a
320
+ * hypothesis. Adoption, validation and authorized uses stay in the record details.
321
+ */
322
+ function certaintyText(definition) {
323
+ const label = EPISTEMIC_LABELS[definition.epistemicState] ?? VALIDATION_LABELS[definition.validationState];
324
+ return `確からしさ: ${label ?? '記録なし'}`;
325
+ }
326
+
268
327
  function detailsFor(record) {
269
328
  return isObject(record?.details) ? record.details : {};
270
329
  }
@@ -310,9 +369,7 @@ function criteriaList(doc, definition, variableMap) {
310
369
  const ref = criterion?.variableRef;
311
370
  const exact = variableMap.get(foundationKey(ref));
312
371
  const exactDefinition = exact ? recordDefinition(exact) : null;
313
- const name = exactDefinition
314
- ? (formatAny(exactDefinition.meaning) ?? referenceLabel(ref))
315
- : referenceLabel(ref);
372
+ const name = (exactDefinition ? formatAny(exactDefinition.meaning) : null) ?? UNNAMED_VARIABLE;
316
373
  const variableDetails = exactDefinition
317
374
  ? [
318
375
  ['定義', exactDefinition.definition],
@@ -328,7 +385,7 @@ function criteriaList(doc, definition, variableMap) {
328
385
  const status = exact ? '参照確認済み' : '参照未確認(基準変数の版が一致しません)';
329
386
  list.append(makeElement(doc, 'li', {
330
387
  className: exact ? '' : 'is-unrecorded',
331
- text: `${name}${variableDetails.length > 0 ? `(${variableDetails.join(' / ')})` : ''}(${referenceLabel(ref)}) ${operator}${target === null ? '' : ` ${target}`} — ${status}`,
388
+ text: `${name}${variableDetails.length > 0 ? `(${variableDetails.join(' / ')})` : ''} ${operator}${target === null ? '' : ` ${target}`} — ${status}`,
332
389
  }));
333
390
  }
334
391
  return list;
@@ -395,7 +452,7 @@ function recordedStateElement(doc, record) {
395
452
  function objectiveCard(doc, record, variableMap) {
396
453
  const definition = recordDefinition(record);
397
454
  const details = detailsFor(record);
398
- const title = formatAny(firstValue(details, 'title')) ?? formatAny(definition.meaning) ?? definition.id;
455
+ const title = formatAny(firstValue(details, 'title')) ?? formatAny(definition.meaning) ?? UNNAMED_RECORD;
399
456
  const gaps = missingObjectiveFields(record);
400
457
  const current = currentStateFor(record);
401
458
  const evaluationPeriod = formatAny(firstValue(details, 'evaluation_period_note', 'evaluationPeriodNote'))
@@ -446,11 +503,16 @@ function objectiveReading(doc, record, variableMap, recordContexts) {
446
503
  const provenance = Array.isArray(definition.provenance) ? definition.provenance : [];
447
504
  section('出典', workspaceDefinition(doc, [
448
505
  ['記録元', recordContexts?.get(record)?.label ?? formatAny(record.source) ?? '未記録'],
449
- ['根拠', provenance.length ? formatStructuredValue(provenance) : '未記録'],
506
+ ['根拠', formatProvenance(provenance) ?? '未記録'],
450
507
  ]));
508
+ const criteriaRefs = Array.isArray(definition.criteria) ? definition.criteria.map((criterion) => criterion?.variableRef) : [];
451
509
  const original = makeElement(doc, 'details', { className: 'bb-fov-original' });
452
510
  original.append(makeElement(doc, 'summary', { text: '記録の詳細・参照・原文' }), objectiveCard(doc, record, variableMap),
453
- workspaceDefinition(doc, [['目的ID', definition.id], ['版', definition.revision], ['digest', record.digest]]));
511
+ workspaceDefinition(doc, [
512
+ ['目的ID', definition.id], ['版', definition.revision], ['digest', record.digest],
513
+ ['基準変数の参照', referenceLabels(criteriaRefs)],
514
+ ['根拠の記録', provenance.length ? formatStructuredValue(provenance) : null],
515
+ ]));
454
516
  body.append(original); return body;
455
517
  }
456
518
 
@@ -477,12 +539,12 @@ function renderObjectives(doc, catalog, viewState, callbacks, recordContexts) {
477
539
  const opener = doc.activeElement;
478
540
  viewState.dialog?.close();
479
541
  viewState.dialog = workspaceDialog(doc, {
480
- title: formatAny(details.title) ?? formatAny(definition.meaning) ?? definition.id, opener,
542
+ title: formatAny(details.title) ?? formatAny(definition.meaning) ?? UNNAMED_RECORD, opener,
481
543
  content: objectiveReading(doc, record, recordContexts?.get(record)?.variableMap ?? variableMap, recordContexts),
482
544
  });
483
545
  },
484
546
  cells: [
485
- { primary: formatAny(details.title) ?? formatAny(definition.meaning) ?? definition.id },
547
+ { primary: formatAny(details.title) ?? formatAny(definition.meaning) ?? UNNAMED_RECORD },
486
548
  current.text ?? current.status ?? '未記録',
487
549
  { text: current.missing.length ? current.missing.join('・') : missingObjectiveFields(record).join('・') || '記録なし', className: 'bb-fov-missing' },
488
550
  formatDate(current.asOf),
@@ -506,13 +568,13 @@ function philosophyApplicability(payload) {
506
568
  const period = validFrom
507
569
  ? `${formatDate(validFrom)}から${validUntil ? ` ${formatDate(validUntil)}まで` : ''}`
508
570
  : null;
509
- return [scope, period ? `適用期間: ${period}` : null].filter(Boolean).join(' / ') || formatStructuredValue(legacy);
571
+ return [scope, period ? `適用期間: ${period}` : null].filter(Boolean).join(' / ') || formatScope(legacy);
510
572
  }
511
573
 
512
574
  function philosophyCard(doc, record) {
513
575
  const payload = record.payload;
514
576
  const card = makeElement(doc, 'article', { className: 'bb-fov-philosophy-card' });
515
- const title = formatAny(payload.title) ?? record.id;
577
+ const title = formatAny(payload.title) ?? UNNAMED_RECORD;
516
578
  card.append(makeElement(doc, 'h3', { text: title }));
517
579
 
518
580
  if (formatAny(payload.statement)) card.append(makeElement(doc, 'p', { className: 'bb-fov-philosophy-statement', text: formatAny(payload.statement) }));
@@ -569,10 +631,10 @@ function renderReferenceList(doc, refs, variableMap, label) {
569
631
  }
570
632
  for (const ref of refs) {
571
633
  const exact = variableMap.get(foundationKey(ref));
572
- const name = exact ? formatAny(recordDefinition(exact).meaning) ?? referenceLabel(ref) : referenceLabel(ref);
634
+ const name = (exact ? formatAny(recordDefinition(exact).meaning) : null) ?? UNNAMED_VARIABLE;
573
635
  list.append(makeElement(doc, 'li', {
574
636
  className: exact ? '' : 'is-unrecorded',
575
- text: exact ? `${name}(${referenceLabel(ref)})` : `${referenceLabel(ref)} — 未接続(変数の版が一致しません)`,
637
+ text: exact ? name : `${name} — 未接続(変数の版が一致しません)`,
576
638
  }));
577
639
  }
578
640
  return list;
@@ -581,16 +643,32 @@ function renderReferenceList(doc, refs, variableMap, label) {
581
643
  function modelCard(doc, record, variableMap) {
582
644
  const definition = recordDefinition(record);
583
645
  const card = makeElement(doc, 'article', { className: 'bb-fov-model-card' });
584
- card.append(makeElement(doc, 'h3', { text: formatAny(definition.meaning) ?? definition.id }));
585
- card.append(makeElement(doc, 'code', { className: 'bb-fov-record-id', text: `${definition.id}@${definition.revision}` }));
586
- card.append(statusElement(doc, definition));
646
+ // The stored scope is ids and a registration time, not the reader's "where it applies"; the
647
+ // record's own words go in front, and the stored scope waits in the details.
648
+ const applicability = definition.applicability ?? definition.scope;
649
+ const registered = isObject(applicability) ? applicability : {};
650
+ const subjects = firstValue(registered, 'subjectIds', 'subject_ids');
651
+ const applicabilityText = formatAny(firstValue(detailsFor(record), 'applicability_text', 'applicabilityText'))
652
+ ?? (isObject(applicability) ? null : formatAny(applicability));
653
+ card.append(makeElement(doc, 'h3', { text: formatAny(definition.meaning) ?? UNNAMED_RECORD }));
654
+ card.append(makeElement(doc, 'p', { className: 'bb-fov-status', text: certaintyText(definition) }));
587
655
  card.append(workspaceDefinition(doc, [
588
656
  ['関係', formatAny(definition.relationship)],
589
- ['適用範囲', formatAny(definition.applicability ?? definition.scope)],
657
+ ['適用範囲', applicabilityText ?? { text: '範囲の説明は記録されていません', className: 'is-unrecorded' }],
590
658
  ['不確かさ', formatAny(definition.uncertainty)],
591
659
  ['入力変数', renderReferenceList(doc, definition.inputVariableRefs, variableMap, '入力変数')],
592
660
  ['出力変数', renderReferenceList(doc, definition.outputVariableRefs, variableMap, '出力変数')],
593
661
  ]));
662
+ card.append(recordDetailsElement(doc, [
663
+ ['状態の内訳', statusText(definition)],
664
+ ['記録ID', definition.id],
665
+ ['版', definition.revision],
666
+ ['digest', record.digest],
667
+ ['登録上の対象', Array.isArray(subjects) && subjects.length > 0 ? subjects.join('、') : null],
668
+ ['登録上の開始日時', formatValidity(firstValue(registered, 'validFrom', 'valid_from'), firstValue(registered, 'validUntil', 'valid_until'))],
669
+ ['入力変数の参照', referenceLabels(definition.inputVariableRefs)],
670
+ ['出力変数の参照', referenceLabels(definition.outputVariableRefs)],
671
+ ]));
594
672
  return card;
595
673
  }
596
674
 
@@ -712,7 +790,7 @@ export function renderFoundationOverview(root, state, {
712
790
  surface.append(workspacePageHeader(doc, {
713
791
  crumbs: ['Brainbase', '目的と現状'],
714
792
  title: '目的と現状',
715
- lead: '選択したプロジェクトの目的、哲学、世界モデルを、登録状態と未確認の点を分けて読みます。',
793
+ lead: '選択したプロジェクトの目的、哲学、世界モデルを、記録された内容と未確認の点を分けて読みます。',
716
794
  source: `正本: ${scopeId}`,
717
795
  }));
718
796
  }
@@ -734,7 +812,7 @@ export function renderFoundationOverview(root, state, {
734
812
  return workspaceDisclosure(doc, { title, help, content, open: viewState[key] ?? initialOpen, onToggle: open => { viewState[key] = open; } });
735
813
  };
736
814
  surface.append(fold('哲学', '判断の前提となる考え方です。登録された本文と、判断への適用範囲を分けて表示します。', renderPhilosophies(doc, catalog, recordContexts), true));
737
- surface.append(fold('世界モデル', '何をすると結果が変わるか、という仮説。未検証・許可用途を分けて確認します。', renderModels(doc, catalog, viewState, callbacks, recordContexts), false));
815
+ surface.append(fold('世界モデル', '何をすると結果が変わるか、という仮説。検証済みか仮説かを先に示し、ほかの状態や記録の番号は各モデルの「記録の詳細」で確認できます。', renderModels(doc, catalog, viewState, callbacks, recordContexts), false));
738
816
  root.append(surface);
739
817
  renderLoadingState(doc, root, viewState, false, onLoading);
740
818
  return surface;
@@ -76,12 +76,25 @@ export function graphOwnShareSource(option, { fetcher } = {}) {
76
76
  });
77
77
  }
78
78
 
79
- /** What the owner sent: the snapshot ID, where it is kept and when it was sent. */
79
+ /** What the owner sent, in words: when it was sent. The snapshot ID and digest are in ownShareHandoverRows. */
80
80
  export function ownShareHandoverText(handover) {
81
81
  if (!isRecord(handover) || !textOrNull(handover.graphId)) return null;
82
- const where = textOrNull(handover.projectCode);
83
- const digest = textOrNull(handover.digest) ?? '未確認';
84
- return `束 ${handover.graphId}(${where ? `置き場所 ${where}、` : ''}digest ${digest}、${formatDateTime(handover.createdAt)} に送信)`;
82
+ return `${formatDateTime(handover.createdAt)} に手元のOSSから送った束`;
83
+ }
84
+
85
+ /** The snapshot ID, where it is kept and its digest, for the record details only. */
86
+ export function ownShareHandoverRows(handover) {
87
+ if (!isRecord(handover) || !textOrNull(handover.graphId)) return null;
88
+ return [
89
+ ['束ID', handover.graphId],
90
+ ['置き場所', textOrNull(handover.projectCode)],
91
+ ['digest', textOrNull(handover.digest) ?? '未確認'],
92
+ ];
93
+ }
94
+
95
+ function handoverDetails(doc, handover) {
96
+ const rows = ownShareHandoverRows(handover);
97
+ return rows ? recordDetails(doc, rows) : null;
85
98
  }
86
99
 
87
100
  /**
@@ -113,6 +126,8 @@ export function ownShareSection(doc, { label, lead = OWN_LEAD, handover, childre
113
126
  const sent = ownShareHandoverText(handover);
114
127
  if (sent) facts.append(makeElement(doc, 'span', { text: sent }));
115
128
  section.append(facts);
129
+ const sentDetails = handoverDetails(doc, handover);
130
+ if (sentDetails) section.append(sentDetails);
116
131
  for (const child of children) if (child) section.append(child);
117
132
  return section;
118
133
  }
@@ -250,7 +265,7 @@ function personText(person) {
250
265
  }
251
266
 
252
267
  function criterionText(criterion) {
253
- const variable = textOrNull(criterion.variable?.meaning) ?? criterion.variable?.id ?? '変数';
268
+ const variable = textOrNull(criterion.variable?.meaning) ?? '名前の記録がない変数';
254
269
  if (criterion.target === null || criterion.target === undefined) return `${variable}(目標値なし)`;
255
270
  const value = `${String(criterion.target)}${textOrNull(criterion.variable?.unit) ? ` ${criterion.variable.unit}` : ''}`;
256
271
  if (criterion.operator === 'at_least') return `${variable}: ${value}以上`;
@@ -295,7 +310,7 @@ export function createOwnObjectivesView({
295
310
  function detail(objective) {
296
311
  const wrap = makeElement(doc, 'div', { className: 'bb-graph-own-detail', attrs: { 'aria-label': '選んだ目的(引き継いだ自分の分)' } });
297
312
  wrap.append(
298
- workspaceRailHead(doc, { kicker: '目的(引き継いだ自分の分)', title: objective.meaning, sub: objective.id }),
313
+ workspaceRailHead(doc, { kicker: '目的(引き継いだ自分の分)', title: objective.meaning }),
299
314
  closeButton(doc, () => controller.select(null)),
300
315
  );
301
316
  const criteria = makeElement(doc, 'ul', { className: 'bb-graph-plain-list' });
@@ -312,7 +327,11 @@ export function createOwnObjectivesView({
312
327
  ['状態', ownLabel(ADOPTION_LABELS, objective.adoptionState) ?? textOrNull(objective.adoptionState)],
313
328
  ['公開範囲(手元での設定)', ownLabel(VISIBILITY_LABELS, objective.visibility) ?? textOrNull(objective.visibility)],
314
329
  ]),
315
- recordDetails(doc, [['目的ID', objective.id], ['版', objective.revision]]),
330
+ recordDetails(doc, [
331
+ ['目的ID', objective.id],
332
+ ['版', objective.revision],
333
+ ['基準変数のID', objective.criteria.map((criterion) => textOrNull(criterion.variable?.id)).filter(Boolean).join('、') || null],
334
+ ]),
316
335
  ],
317
336
  }));
318
337
  return wrap;
@@ -344,7 +363,7 @@ export function createOwnObjectivesView({
344
363
  selected: objective.id === state.selectedId,
345
364
  onSelect: (id) => controller.select(id),
346
365
  cells: [
347
- { primary: objective.meaning, secondary: objective.id },
366
+ { primary: objective.meaning },
348
367
  ownLabel(ADOPTION_LABELS, objective.adoptionState) ?? String(objective.adoptionState ?? ''),
349
368
  periodText(objective.evaluationPeriod),
350
369
  personText(objective.accountable) ?? { text: '未登録', className: 'is-unresolved' },
@@ -365,7 +384,7 @@ export function createOwnObjectivesView({
365
384
  if (compact) {
366
385
  const facts = makeElement(doc, 'p', { className: 'bb-graph-own-facts', text: '読み取りのみ' });
367
386
  const refs = makeElement(doc, 'details');
368
- refs.append(makeElement(doc, 'summary', { text: '出典' }), makeElement(doc, 'p', { text: ownShareHandoverText(handover) ?? (state.list.state === 'not_handed_over' ? 'まだ引き継いでいません。' : '出典は確認できません。') }));
387
+ refs.append(makeElement(doc, 'summary', { text: '出典' }), makeElement(doc, 'p', { text: ownShareHandoverText(handover) ?? (state.list.state === 'not_handed_over' ? 'まだ引き継いでいません。' : '出典は確認できません。') }), handoverDetails(doc, handover));
369
388
  root.replaceChildren(facts, ...body(), refs);
370
389
  }
371
390
  else root.replaceChildren(ownShareSection(doc, { label: source.label, lead: OBJECTIVES_LEAD, handover, children: body(), className: 'bb-graph-own-objectives' }));