Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ concurrency:
cancel-in-progress: false

env:
EDITOR_MANIFEST_SHA256: 3e0510de27b93c5aed5018058b55bd82798ad7ed535fd1c25812aef5a0aadc03
EDITOR_MANIFEST_SHA256: e972d1c779cca709ff1a1c8e0b0c543b855d82d7e6fa26fbf14414f84c6fb1d0
ZOLA_VERSION: "0.22.1"
CF_PROJECT: terraphim-ai
OP_API_TOKEN: op://TerraphimPlatform/terraphim-md-book-cloudflare/workers-api-token
Expand Down
6 changes: 4 additions & 2 deletions content/capabilities/terraphim-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ Terraphim Editor brings knowledge-graph alternative suggestions into your writin

## Keep your decisions and alternatives

Attach alternatives to words, sentences and paragraphs. Save an annotated Markdown document and reopen it with those choices preserved. Newly authored alternatives register as document-scoped synonyms using `synonyms::` syntax; they do not silently update the shared graph used by other tools.
Attach alternatives to words, sentences and paragraphs. Save an annotated Markdown document and reopen it with those choices preserved. Newly authored alternatives register as document-scoped synonyms using `synonyms::` syntax; download them through Knowledge graph to use that exact vocabulary in terraphim-grep. Sharing is explicit and does not silently alter your active role.

Ghost passages to retain them outside clean export, set notes aside in Overflow, and inspect possible cuts in the Lab. KG-protected Trim preserves matched concepts and their original spelling, including supported Unicode normalization.

The editor runs as WebAssembly in your browser. Editing with the bundled graph does not require an LLM or sending your document to a provider.

## See actual saved outputs

[Watch the captioned editor and terraphim-grep walkthroughs](/how-tos/knowledge-work-editor/): Chrome, Safari, Firefox and the existing Zed extension, followed by search with the same shared KG, with and without synthesis. Each video identifies its recorded scope; the current browser build includes the later Unicode normalization repair.
[Watch the 80-second alternative-to-search story](/how-tos/synonym-search/): create Concern as an alternative to Risk, share the graph and find related decisions, with and without synthesis.

[Earlier captioned browser and extension walkthroughs](/how-tos/knowledge-work-editor/): Chrome, Safari, Firefox and the existing Zed extension, followed by search with the same shared KG, with and without synthesis. Each video identifies its recorded scope; the current browser build includes the later Unicode normalization repair.

This is a preview. Complete acceptance against all 41 source-video requirements remains open, including Safari dragging and some visual/native cases. The existing Zed extension demonstrates its supported capabilities; the separate Zed fork is outside this publication.

Expand Down
4 changes: 4 additions & 0 deletions content/how-tos/knowledge-work-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ description = "Try Terraphim Editor, then inspect search results with and withou
date = 2026-10-11
+++

[Watch the new 80-second story: create a synonym, share it, then search](/how-tos/synonym-search/)

These earlier host recordings remain available as versioned evidence. The new story above follows the current alternative-to-search flow.

[Try Terraphim Editor](/editor/)

Keep alternatives attached to words, sentences and paragraphs. Ghost a passage without losing it, stash notes in Overflow, and use the Lab to inspect possible cuts. The editor runs as WebAssembly in your browser with a bundled local knowledge graph.
Expand Down
62 changes: 62 additions & 0 deletions content/how-tos/synonym-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
+++
title = "Different words. The same idea."
description = "Create a wording alternative, share its knowledge graph, and find related decisions with terraphim-grep."
date = 2026-10-11
[taxonomies]
categories = ["How-tos"]
tags = ["editor", "knowledge-graph", "search"]
+++

Your project brief says **risk**. Later, you search for **concern**. Terraphim connects the two so a change of wording does not hide the decisions you need.

<video controls preload="metadata" playsinline poster="/demos/synonym-search/poster.jpg" style="width:100%;max-width:1100px" aria-label="Create an alternative, share its graph, and search with it — 80 seconds"><source src="/demos/synonym-search/synonym-search-story.mp4" type="video/mp4"><track kind="captions" src="/demos/synonym-search/captions.vtt" srclang="en" label="English">[Watch the 80-second story](/demos/synonym-search/synonym-search-story.mp4)</video>

[Try Terraphim Editor](/editor/) · [Read the narration](/demos/synonym-search/transcript.txt)

## Choose the words that fit

In our community garden brief, timber might arrive late. The team has decided to keep a backup supplier. Add **Concern** as an alternative to **Risk**, then swap between them. The other wording stays attached to the document.

## Share what those words mean

Open **Knowledge graph** from the Markdown export menu. The editor shows **Risk ↔ Concern** and its actual definition:

```text
synonyms:: Risk, Concern
```

Download the graph and the clean text. This explicitly shares the document's authored synonym groups as a Terraphim thesaurus; it does not silently change your active role. The saved example contains **Risk**, with no literal occurrence of **Concern**.

## Find the decisions using either word

Use the graph downloaded from that editing session:

```sh
terraphim-grep concern --thesaurus knowledge-graph.json --paths corpus -C 2 --json
```

The actual result contains three risk passages and their related decisions, with file and line locations. No generated answer is requested.

Add `--answer` to the same command for synthesis:

```sh
terraphim-grep concern --thesaurus knowledge-graph.json --paths corpus -C 2 --json --answer
```

The video shows the generated summary and its references to the same three passages. Decisions remain decisions: the source does not establish whether they have been carried out. Check the evidence alongside any generated answer.

Editing and local search use your local data. Optional synthesis sends the retrieved passages to your configured model provider.

## Try the exact files

- [The graph downloaded in the recording](/demos/synonym-search/knowledge-graph.json)
- [The clean project brief](/demos/synonym-search/project-brief.md) — place it in a `corpus` directory
- [Saved Markdown with alternatives](/demos/synonym-search/annotated.md)
- [Actual result without synthesis](/demos/synonym-search/without-synthesis.json)
- [Actual result with synthesis](/demos/synonym-search/with-synthesis.json)

The community garden brief is authored public sample input. The alternatives, downloaded graph, retrieved passages and generated answer are actual outputs. The command-line section displays those JSON fields in a readable presentation; it is not a separate Terraphim interface. The voice is synthetic British English (Emma). Setup is omitted, and the recorded interaction runs at its original speed. [Recording details and file identities](/demos/synonym-search/manifest.json).

This is a preview of the new export and search flow. It uses the [editor graph-sharing candidate](https://git.terraphim.cloud/terraphim/terraphim-editor/pulls/131) and the [grep synonym/synthesis candidate](https://git.terraphim.cloud/terraphim/terraphim-clients/pulls/385); older installed binaries may differ. A fresh synthesis run may produce different wording.

[Earlier browser and Zed host walkthroughs](/how-tos/knowledge-work-editor/) retain their own recorded versions and limitations. This focused story does not qualify all 41 source-video requirements. The Zed fork remains separate.
12 changes: 8 additions & 4 deletions docs/editor-publication.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ Before deployment, verify both source assets and Zola output with that independe

```bash
python3 -m unittest discover -s scripts -p test_import_editor.py -v
python3 scripts/import-editor.py --verify --destination static/editor --manifest-sha256 3e0510de27b93c5aed5018058b55bd82798ad7ed535fd1c25812aef5a0aadc03
python3 scripts/import-editor.py --verify --destination static/editor --manifest-sha256 e972d1c779cca709ff1a1c8e0b0c543b855d82d7e6fa26fbf14414f84c6fb1d0
zola build
python3 scripts/import-editor.py --verify --destination public/editor --manifest-sha256 3e0510de27b93c5aed5018058b55bd82798ad7ed535fd1c25812aef5a0aadc03
python3 scripts/import-editor.py --verify --destination public/editor --manifest-sha256 e972d1c779cca709ff1a1c8e0b0c543b855d82d7e6fa26fbf14414f84c6fb1d0
```

Use Zola 0.22.1, matching deployment. A different installed Zola version is not the deployment build.

Import a replacement into a fresh directory using `scripts/import-editor.py --source BUILD --manifest MANIFEST --manifest-sha256 APPROVED_DIGEST --destination NEW_DIRECTORY`. Review source identity, runtime closure and browser output evidence before changing the independent pin. Never derive the expected digest from the mutable deployed receipt during verification.

The current bundle was staged from clean editor commit `949b5252e89814ed294c1a238cef726663873a76`, including the independently reviewed Unicode KG-protected Trim repair. Confirm that this source is admitted to the editor release chain before promoting this website candidate. Deployment and HTTPS/browser acceptance are separate gates. Safari dragging and complete 41-requirement acceptance remain unresolved. A stock Zed capability preview is not custom visual parity; the fork is outside this change.
The current bundle was staged from clean editor commit `4050ac9a35e1255ebc3f1d7cd50eb0dd97059730`, including the Unicode KG-protected Trim repair and reviewed document-synonym export. Confirm that this source is admitted to the editor release chain before promoting this website candidate. Deployment and HTTPS/browser acceptance are separate gates. Safari dragging and complete 41-requirement acceptance remain unresolved. A stock Zed capability preview is not custom visual parity; the fork is outside this change.

The how-to uses authored public input and an existing shared KG. New alternatives are document-scoped synonyms. The paired grep synthesis demonstration requires the clients candidate with synonym retrieval, semantic coverage and explicit `--answer` fixes; an older installed binary may behave differently. Configured provider synthesis may send public retrieved text outside the device.
The new synonym-search how-to uses authored public input, then creates Concern as an alternative to Risk and downloads the actual document synonym graph. The CLI consumes those exact downloaded bytes. The older host walkthroughs retain their existing shared-KG demonstration and recorded limitations. The paired grep synthesis demonstration requires the clients candidate with synonym retrieval, semantic coverage and explicit `--answer` fixes; an older installed binary may behave differently. Configured provider synthesis may send public retrieved text outside the device.

## Public walkthrough media

Expand All @@ -28,3 +28,7 @@ The recorded browser candidate remains `e2ee3ff9f6133cd67cd15533109c8020c20a0cdf
Unicode repair verification:110 native library tests, six original protection tests, eight Unicode regressions, strict native/WASM Clippy, real Chrome Trim reduction, Done ghosts, exact annotated save/reopen and undo/redo. Existing Terraphim normalized term and matcher types are reused; NFC and original grapheme boundary mapping are added. Greek sigma variants are equivalent; general full case folding and Straße/STRASSE transliteration are not claimed. Exact original spelling is retained.

The paced-v2 media edition adds burned-in explanatory text outside the app image and replaces idle-heavy walkthroughs with disclosed chronological cuts and1.5–3× speed changes. Overview77s, Chrome44s, Firefox49s, Safari45s, Zed60s, grep21s. Original footage, source identity and qualification limits remain unchanged. The manifest records every retained source range and output caption interval.

## Focused synonym-search story

The 80-second story at `/how-tos/synonym-search/` supersedes the previous overview as the homepage demo. It records editor `4050ac9a35e1255ebc3f1d7cd50eb0dd97059730` and clients `f0410af`, with natural-rate British female synthetic narration. Editor-created graph and clean text are actual downloads; identical chunks are verified with synthesis off/on. CLI JSON fields are presented readably with original strings retained. See `/demos/synonym-search/manifest.json` for the media and artifact identities.
4 changes: 2 additions & 2 deletions scripts/test_publication_media.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ def test_walkthrough_links_and_disclosures(self):
for text in ['41 requirements', 'zero cuts', 'overstates', 'document-scoped synonym', 'Zed fork is separate', 'normalization repair']:
self.assertIn(text, page)
home = (ROOT / 'themes/WarpDrive/templates/index.html').read_text()
self.assertIn("get_url(path='editor/')", home)
self.assertIn("get_url(path='@/how-tos/knowledge-work-editor.md')", home)
self.assertIn('href="/editor/"', home)
self.assertIn('href="/how-tos/synonym-search/"', home)


if __name__ == '__main__':
Expand Down
57 changes: 57 additions & 0 deletions scripts/test_synonym_story.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
"""Verify actual editor exports, CLI results and publication media identities."""
import hashlib
import json
from pathlib import Path
import unittest

ROOT = Path(__file__).resolve().parents[1]
MEDIA = ROOT / 'static/demos/synonym-search'


class SynonymStoryTests(unittest.TestCase):
def test_export_is_used_for_search_and_synthesis(self):
graph = json.loads((MEDIA / 'knowledge-graph.json').read_text())
self.assertEqual(graph['data']['risk']['id'], graph['data']['concern']['id'])
self.assertNotIn('concern', (MEDIA / 'project-brief.md').read_text().lower())
off = json.loads((MEDIA / 'without-synthesis.json').read_text())
on = json.loads((MEDIA / 'with-synthesis.json').read_text())
self.assertIsNone(off['answer'])
self.assertEqual(off['chunks'], on['chunks'])
self.assertEqual(len(off['chunks']), 3)
lines = (MEDIA / 'project-brief.md').read_text().splitlines()
for chunk in off['chunks']:
self.assertEqual(chunk['source'], 'project-brief.md')
self.assertEqual(chunk['content'], '\n'.join(lines[chunk['line_start'] - 1:chunk['line_end']]))
for citation in on['answer']['citations']:
self.assertEqual(citation['source'], 'project-brief.md')
self.assertEqual(citation['excerpt'], lines[citation['line'] - 1])
self.assertTrue(on['answer']['answer'])
self.assertEqual(len(on['answer']['citations']), 3)

def test_media_and_outputs_match_reviewed_manifest(self):
manifest = json.loads((MEDIA / 'manifest.json').read_text())
self.assertGreaterEqual(manifest['durationSeconds'], 60)
self.assertLessEqual(manifest['durationSeconds'], 90)
self.assertTrue(manifest['voice']['synthetic'])
self.assertTrue(manifest['voice']['speechRateUnchanged'])
for entry in manifest['files']:
data = (MEDIA / entry['file']).read_bytes()
self.assertEqual(hashlib.sha256(data).hexdigest(), entry['sha256'])
self.assertEqual(len(data), entry['bytes'])
self.assertEqual(manifest['checks']['pageErrors'], [])
self.assertTrue(manifest['checks']['sameRetrievedChunks'])
self.assertTrue(manifest['checks']['sameGraphAndTextAsPriorVerifiedRun'])

def test_main_story_is_linked_and_scope_is_clear(self):
page = (ROOT / 'content/how-tos/synonym-search.md').read_text()
home = (ROOT / 'themes/WarpDrive/templates/index.html').read_text()
self.assertIn('href="/how-tos/synonym-search/"', home)
for text in ['synonyms:: Risk, Concern', '--answer', 'authored public sample input',
'synthetic British English', 'does not qualify all 41', 'Zed fork remains separate']:
self.assertIn(text, page)
for file in ['synonym-search-story.mp4', 'knowledge-graph.json', 'project-brief.md', 'without-synthesis.json', 'with-synthesis.json']:
self.assertIn('/demos/synonym-search/' + file, page)


if __name__ == '__main__':
unittest.main()
44 changes: 44 additions & 0 deletions static/demos/synonym-search/annotated.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Community garden launch


Goal: Open the garden for spring planting.


Risk: Timber may arrive late. Decision: Keep a backup supplier.


Risk: Rain may delay planting. Decision: Reserve a covered area.


Risk: Volunteers may cancel. Decision: Keep a reserve list.

```terraphim-alternatives
{
"version": 1,
"spans": [
{
"id": "s1",
"kind": "word",
"anchor": {
"start": 73,
"end": 77,
"text": "Risk",
"before": " garden for spring planting.\n\n\n",
"after": ": Timber may arrive late. "
},
"active": 0,
"alts": [
{
"text": "Risk",
"source": "original"
},
{
"text": "Concern",
"source": "human"
}
]
}
],
"ghosts": []
}
```
58 changes: 58 additions & 0 deletions static/demos/synonym-search/captions.vtt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
WEBVTT

00:00:00.250 --> 00:00:04.443
When people use different words for the same idea, useful decisions can

00:00:04.443 --> 00:00:06.190
become surprisingly hard to find.

00:00:07.250 --> 00:00:10.852
Here is our community garden brief. It records three risks, and the

00:00:10.852 --> 00:00:13.553
decisions we have made to deal with each one.

00:00:15.250 --> 00:00:18.996
I add concern as an alternative to risk. Now I can swap

00:00:18.996 --> 00:00:22.742
between the two words, choosing the wording that fits without losing the

00:00:22.742 --> 00:00:23.366
other option.

00:00:26.250 --> 00:00:30.840
The editor connects those alternatives to one idea in the knowledge graph.

00:00:30.840 --> 00:00:35.047
Here is the actual synonym definition: risk and concern belong together.

00:00:37.250 --> 00:00:41.059
I download that graph and the finished text. Notice that I leave

00:00:41.059 --> 00:00:43.915
risk in the document. The word concern is absent.

00:00:46.250 --> 00:00:50.497
Now I search for concern using the graph I just downloaded. It

00:00:50.497 --> 00:00:54.744
finds all three risk passages, including the related decisions, even though the

00:00:54.744 --> 00:00:55.805
wording is different.

00:00:58.250 --> 00:01:02.632
Without synthesis, I get the original passages and their locations. Adding the

00:01:02.632 --> 00:01:07.014
answer flag gives me a summary from the same evidence, with source

00:01:07.014 --> 00:01:07.379
references.

00:01:10.250 --> 00:01:14.735
The summary keeps decisions distinct from completed actions. From choosing a word

00:01:14.735 --> 00:01:19.219
to finding a decision, the same knowledge graph keeps the meaning connected.
17 changes: 17 additions & 0 deletions static/demos/synonym-search/knowledge-graph.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"data": {
"concern": {
"display_value": "Risk",
"id": 1,
"nterm": "risk",
"pinned": false
},
"risk": {
"display_value": "Risk",
"id": 1,
"nterm": "risk",
"pinned": false
}
},
"name": "Document alternatives"
}
Loading
Loading