← Plugin catalog
Productivity

Wikilayer

Maxim Oranskiy PR Novi Sad v2.1.0

Create and edit wiki pages

Create a free account to save this plugin.

Competitor profile

Developer declarations; not independently tested. Listing last checked Nov 4, 2026. Package observed Nov 3, 2026.

Cost & access

Wikilayer does not sell products or process payments.

Declared limitations

  • Booking travel
  • Editing another website
  • Another user's private wiki

Not specified in the available declarations: capabilities.

Onboarding example

Make me a wiki covering all the main London airports.

View onboarding source →

View package source →

Description

From the marketplace listing

Wikilayer is a wiki ChatGPT can read and edit. Ask it to draft a page, reorganise a section, or pull a fact from existing content, and the changes appear at a wikilayer.org URL with a normal wiki interface — pages, headings, blocks, and a table of contents. ChatGPT navigates the wiki by outline and fetches only the blocks it needs, so it can keep working with the wiki as it grows past what fits in one conversation. Wikilayer reads and writes only the wikis your connected account can reach. A new wiki is private; a public one is readable by anyone on the web, so ChatGPT asks before making a wiki public, sharing a page by link or deleting pages.

Language: English · Automatically detected from descriptions.

Screenshots

From the developer.

What changed

Keywords

Files & skills

File archives

Plugin package11 files · 1.13 MBBrowse files →
Skill instructions
get-started1.45 KB

View saved version →

---
name: get-started
description: First steps with Wikilayer. Find or create a wiki, read its rules, write a first page and hand back its link. Use when the user is new to Wikilayer or asks what it can do.
---

# Get started with Wikilayer

Wikilayer is a wiki the user reads in the browser and you edit through its tools. A wiki holds pages; a page holds blocks, one per section.

1. Call `list_wikis` to see the wikis this account can read and the role it holds in each.
2. If the user has none, or wants a new one, call `create_wiki`. It is private unless the user asks for a public one. Say so before making a wiki public: everything written to it is then readable on the open web and indexed by search engines.
3. If a call is refused because the wiki has rules, read them with `get_page_markdown(wiki_id=…, special_role='rules')` and pass the value it returns in `rules_read_and_agreed` on later calls. Follow those rules while writing there.
4. Before writing into an existing wiki, read its structure with `get_outline` so new pages land where a reader would look for them.
5. Write with `create_nodes`: a page per subject, a block per section of a page. Do not type `#` headings into a body; a section is its own block.
6. After every write, give the user the link to what changed: join the response's `base_url` and the node's `url_path`.

Ask before deleting pages, changing a wiki's visibility or sharing a page by a public link: these change what other people can see.
lint9.94 KB

View saved version →

---
name: lint
description: "Final polish of a Wikilayer page, a list of pages or a wiki after review has finished and substantive edits are settled. Checks wording, marks, links, voice, quotations, and prose flow. Advisory only; never edits."
---

# wikilayer:lint

Advisory pass over the surface of the text. It is the last of three steps: the author reads every page the edit affects whole and fixes what that shows, then review, then this. Run it only once changes to claims or structure are settled. Read each block, apply the check list, emit a markdown report grouped by page. Do not apply fixes.

This skill reads the text. Nothing it finds can become false: a mark, a phrasing, a paragraph that lost its thread is not wrong later, only worse to read, so the fix happens while the author is already in the node and never sends anyone back to re-read the page. What can become false belongs to the review skill, which reads the tree and the claims. Keep the two reports apart: merged into one list, the cheap findings crowd out the expensive ones, and the cheap ones get done because they are cheap.

The checks below mirror https://wikilayer.org/smee-again/wikilayer-howto/54729-wording, the primary source. They are duplicated here on purpose: the skill must run self-contained against any wikilayer instance, including a localhost one with no authoring guide present, so it never fetches the manual at lint time. When that page gains or changes a rule, mirror it here. The wiki's own rules page is another matter: those are the terms of the wiki being linted, and step 2 reads them.

## Procedure

1. Resolve the target from the user's request (numeric id, URL, or unambiguous wiki/page name). If it is missing or ambiguous, ask. Resolve its owning wiki with `list_wikis(wiki_ids=[...])`. Pages nest: a page sits under the wiki or under another page. A wiki whose `list_wikis` row has `pages_tree=false` is in the old flat mode, where every ordinary page hangs from the wiki.

   **Scope: whole wiki, one page, or a list of pages.** Read each target's `kind` with `get_outline` or `get_node`. A `wiki` target lints every page in the facet; a `page` target lints that page and its blocks, not descendant pages; a list of pages, all in one wiki, lints each as a page target. Every check runs per page either way. Use a page target or a list for a focused pass after an edit; a wiki target for a full audit.

   A link from a page to one of its child pages points at another page, so it is not a same-page link.

   **Pick the language facet.** `get_outline` rows carry a `language` field. If the wiki is monolingual, the whole wiki is the facet and the rest runs unchanged. If it is multilingual, lint one language at a time: take the target language from the user's request (for example `wiki 1 in en`), otherwise default to the wiki's primary language. Every check below runs on the **target-language facet** only, the nodes whose effective language is the target (an empty `language` inherits the primary). State the facet in the report header. A page target is already one language. A page's translation twin in another language is not a duplicate; checking a translation against its source is the job of `wikilayer:translations`.
2. Read and accept any rules the Wikilayer server requires before protected reads, then carry the returned agreement token on every call it binds. Read the wiki's own rules page whole (`get_page_markdown(wiki_id=<wiki-id>, special_role='rules')`), not only to sign it: a block there titled `wikilayer:lint` is this wiki's checklist for this skill, such as a word list its text is held to. Run its checks on every node in scope as further checks, cite the block in each finding they produce, and follow its links to the material it names, such as the word list itself. They add to the checks below and never remove, soften or override one, nor this skill's boundary with review; a checklist item that can become false is review's and is left to it. A wiki without such a block adds nothing. This mirrors https://wikilayer.org/smee-again/wikilayer-howto/55269-wiki-rules#block-59952. Read the complete outline with `get_outline(<wiki-id>, max_depth=-1)`, supplying the pagination arguments exposed by the client and continuing until `has_more` is false. No finite depth is a complete-outline request: a configured or accidental level beyond it would silently disappear from the audit. Use `tokens` and `child_count` on each row as first-pass signals to budget per-page work, and the `language` field to keep to the facet. Tool names may be namespaced by the client; use the exposed Wikilayer tool whose final name matches the operation named here.
3. Read every page in scope yourself with `get_page_markdown(<page-id>)` and run the checks below on it: a proof-of-work line per clean node, a full finding with cited quote per violation. Do not hand pages to other agents.

   Read the verbatim source, never a paraphrase: do **not** WebFetch the page or its `.md` URL. WebFetch routes the page through a model that can reword or reorder it, which is fatal for checks like em-dash use, which only mean anything against the exact bytes. The tool returns the stored markdown untouched.

   Two things in that document come from the engine, not the author, and are never findings: the `<!-- block:N -->` comment above each node, which is how a finding cites the node it belongs to, and the closing `## Links here` section after a `---` rule.
4. Emit one markdown report, grouped by page. Never write back to the wiki.

## Checks

Each is a "smart prompt": the signal flags a candidate, the agent judges whether it's a real issue in context.

1. **Em-dash.** The em-dash (`—`) is a rare mark, earned, not default punctuation. Flag every occurrence and judge whether it is the seldom case where nothing else carries the meaning; almost always a comma, colon, period, or parentheses is the fix. Do not wave `—` through as "one per page is fine".

   The paragraph above is an English convention, not a universal one, so first establish what the facet's language does with the mark. Where it is ordinary punctuation there, or required outright, the dash is spelling and this check does not run on the page at all: German sets off an aside with one freely, and Russian puts one between subject and predicate when the copula is absent, where omitting it is the error. Those two are examples and not the list — check the language in front of you rather than matching it against them, because running the English rule over a language that does not share it produces a finding on every page in the wiki.
2. **Link text.** The link text is the subject being talked about, woven into the sentence as a noun, because a reader knows subjects and not pages. Strip the links and read the sentence again: if it still states its point, the link earned its place. `Click [here](...)`, `see [the documents page](page:N)` and `details on [Other Page]` all fail that read; `[tenge](page:6564) was introduced in 1993` passes. Flag three forms: the wiki's own furniture used as the anchor ("page", "section", "see"), quotation marks around the title, and a link to one article anchored on the publisher rather than on what the article did.
3. **One-line paragraphs that should be a list.** One-sentence paragraphs in a row, sharing a parallel structure, read as sequential steps, and the reader has to work out that they belong together. Bullets carry "these belong together" for free. This is the `p` against `ul` case, and it is this skill's because the same items promoted to nodes would change the outline, which is review's call and not this one's. Where an item has grown past a line, say so and stop: promoting it is review's.
4. **Same-page links.** A link from a block to another block of the page it sits on. The reader already has that page, so the link gives nothing.
5. **Voice.** Neutral and encyclopedic: concrete numbers rather than evaluative words, and the object named. The test is whether a sentence could be moved to another wiki on another subject and still read as written; "a significant improvement" and "the exchange" survive that move, "17% fewer steps" and "exchanging dinars for forints" do not.
6. **Quotation form.** A quotation belongs in a blockquote, or it gets lost in dense prose. Where a translation is given alongside the original, the original comes first and the translation follows in italics inside the same blockquote. Whether a translation is owed at all is not this skill's call.
7. **A block that loses its thread.** Read each block as prose rather than as a checklist. Topic jumps, a paragraph that does not continue the one before it, a reason given after the thing it explains: flag the place and say where the thread breaks. Nothing here is false, only harder to follow than it needs to be.
8. **Words that say nothing.** A long block gets skimmed, so a word that adds nothing costs the block its reader. Write the shorter version: quote what goes, show what stands. A verdict with no rewritten text is not a finding, and a cut counts only when the shorter version is visibly shorter and still says everything the original said. A block already as short as its claim allows earns a proof-of-work line and nothing else; this is the check most prone to inventing work. Where the same thing is said in two places rather than at length in one, that is review's, because tomorrow one of the two is edited.

## What a finding here is worth

Every finding is the same weight: worth fixing, never worth a pass of its own. Say so in the report, and do not recommend running this skill again after the author has acted, because nothing here changes what the wiki asserts and the page that comes back is the same page.

A candidate that does not fit a check above is not a lint finding. If two places say different things, if a node sits where nobody will look for it, if a heading has swallowed its body or a body restates what the engine already keeps, hand it to the review skill rather than reporting it here. Those can become false, and something that can become false earns a second reading; these cannot, and do not.
review18.4 KB

View saved version →

---
name: review
description: "Review the coherence of a Wikilayer page, a list of pages or a whole wiki after recent edits, once you have read them whole yourself and fixed what you found: a check on finished work, not a way to finish it. Advisory only; never edits."
---

# wikilayer:review

Read the wiki as the person who came to it for something, and report what the arrangement told them. The arrangement of nodes is itself a claim: where a node sits says that these are of one kind, that this follows from that, that this is the exception. Recommendations only. Do not edit.

This skill reads as a reader; lint reads the text. Everything found here can become false, which is why a finding here earns a second reading of the page and a lint finding never does. Keep the two reports apart: merged into one list the cheap findings crowd out the expensive ones, and the cheap ones get done first because they are cheap.

**This skill does not check form.** Marks, the em-dash, wording, voice, the shape of a paragraph, a block that lost its thread or spends more words than its claim needs: all lint's, and reporting one here is a defect in the run. A typographic marker inside a body — a bold lead-in, a horizontal rule, a bullet that runs for paragraphs — is at most the trace of a claim that never became a node. The finding is the claim, quoted, and the fact that the outline does not show it; the marker is how you noticed, never what you report, and a count of markers is not a finding at all. Nothing here is decided by counting.

The categories below mirror https://wikilayer.org/smee-again/wikilayer-howto/54721-pages-and-nodes and the principles they come from at https://wikilayer.org/smee-again/wikilayer-howto/59315-writing-a-wiki, duplicated here so the skill runs self-contained against any wikilayer instance, including one with no authoring guide present. When either page gains or changes a rule, mirror it here.

## Procedure

One agent runs the whole review, and not the one that wrote the pages: the author reads what they meant. Before the run, the author reads every page the edit affects, whole, as a reader who does not know the author's intent, and fixes what that reading shows. Review is a check on finished work, not a way to finish it: a reviewer is for what the author cannot see from inside, and a slip visible on a first reading costs a review here. Many findings mean the caller skipped that reading, so the caller goes back to it rather than into another round. This mirrors https://wikilayer.org/smee-again/wikilayer-howto/54798-editing-a-wiki#block-54803.

1. Resolve the target from the user's request (numeric id, URL, or unambiguous wiki/page name). If it is missing or ambiguous, ask. Resolve its owning wiki with `list_wikis(wiki_ids=[...])`. Pages nest: a page sits under the wiki or under another page, and that page tree is the wiki's navigation. A wiki whose `list_wikis` row has `pages_tree=false` is in the old flat mode, where every ordinary page hangs from the wiki and nothing in the chrome lists pages; there, report no missing page parent or unasserted kinship, and treat a page without inbound links as unreachable.

   **Scope: whole wiki, one page, or a list of pages.** Read each target's `kind` with `get_outline` or `get_node`. A `wiki` target runs the full procedure; a `page` target reviews that page and its blocks, not descendant pages, and skips the wiki-level synthesis in step 4. A list of pages, all in one wiki, reviews each as a page target and then runs step 4 across the listed pages only. A page review still reads the target page's immediate page parent, page siblings and child-page titles as structural context for category 2; it does not review their bodies. Reach for a page target when one page was just added or reworked, a list when an edit touched several pages, and a wiki target for the periodic whole-body pass.

   **Pick the language facet.** `get_outline` rows carry a `language` field; collect the distinct languages present. If the wiki is monolingual, the whole wiki is the facet and the rest of this procedure runs unchanged. If it is multilingual, this skill audits one language at a time: take the target language from the user's request (for example `wiki 1 in en`), otherwise default to the wiki's primary language (the root's language). Every step below operates on the **target-language facet** only, the nodes whose effective language is the target (an empty `language` inherits the primary). State the facet in the report header. A page target is already one language, so it needs no facet choice.

   A language twin is the same topic in another language, never a finding. A page and its translation are not a contradiction, not missed DRY, not a duplicate. Checking a translation against its source is the job of `wikilayer:translations`, not this skill, so nodes outside the target facet stay out of scope for this run.
2. Read and accept any rules the Wikilayer server requires before protected reads, then carry the returned agreement token on every call it binds. Read the wiki's own rules page whole (`get_page_markdown(wiki_id=<wiki-id>, special_role='rules')`), not only to sign it: a block there titled `wikilayer:review` is this wiki's checklist for this skill. Run its checks on every page in scope as further categories, cite the block in each finding they produce, and order those findings with the rest. They add to the categories below and never remove, soften or override one, nor this skill's boundary with lint; a checklist item about form is lint's and is left to it. A wiki without such a block adds nothing. This mirrors https://wikilayer.org/smee-again/wikilayer-howto/55269-wiki-rules#block-59952. Read the complete outline with `get_outline(<wiki-id>, max_depth=-1)`, supplying the pagination arguments exposed by the client and continuing until `has_more` is false. No finite depth is a complete-outline request. Use it as the structural map of the facet, and keep each row's `parent_id`, `depth`, `tokens` and `child_count`: categories 2, 7 and 8 depend on them. On a multilingual wiki the facet home is the target language's home (the wiki root for the primary language, the root's translation twin for another). Tool names may be namespaced by the client; use the exposed Wikilayer tool whose final name matches the operation named here.
3. Read every page in scope yourself with `get_page_markdown(<page-id>)`, which returns it whole and in reading order, and run the per-page categories below on it. Do not hand pages to other agents: the review exists for how the pages read together, and a reader who saw one page cannot see that.

   Read the verbatim source, never a paraphrase: do **not** WebFetch the page or its `.md` URL. WebFetch routes the page through a model that can silently reword or reorder content, which corrupts an exact-text audit (a block list was observed reordered this way). The tool returns the stored markdown untouched.

   Two things in that document are the engine's, not the author's: the `<!-- block:N -->` comment above each node, which is how a finding cites the node it belongs to, and the closing `## Links here` section after a `---` rule. Neither is ever a finding, and the rule before the section is not a heading smuggled into a body. Its absence is the evidence category 8 reads: a page whose document ends without one is a page nothing points at.
4. **(Wiki or list target.)** Once every page in scope is read, run the wiki-level categories across them: contradictions, missed DRY and structural grouping, within the target facet, and for a list within the listed pages. Skip it and the run is a stack of page reviews, which is what the target was chosen not to be.

   Before reporting a contradiction, re-read the two blocks it names.
5. Emit one markdown report, its findings ordered as the closing section says rather than grouped by the category that produced them. Never write back to the wiki.

## Categories

Per-page (judged from each page's text):

1. **The outline against the page.** Read the titles alone first and stop there, because that is the whole map a reader has when deciding what to open. Say what you expect each node to hold. Only then read the bodies, and report every place the map was wrong.

   It goes wrong three ways, and each is reported as what it costs a reader:

   - a claim standing in a body that no title carries, so only someone who opened that body will ever learn it;
   - a title promising more than its body delivers, or promising something else, so a reader takes the wrong thing off the outline and has no reason to open it and find out;
   - two sibling titles you could not tell apart, so the outline stops being a map at that point.

   What a title is for depends on its level. At h2 the title names a section in a few words and never states the claim: the top level is read as a table of contents, and a sentence there competes with the page's own title. A single assertive h2 among ordinary ones is a finding on its own; a whole top level of them is a page written in one pass with no sections, and then say which sections its blocks fall into. From h3 down the title states the claim and the body argues it, so a title there that promises nothing keeps its claim off the outline.

   A page whose outline is only h2 is the same defect arriving the other way, and the one to check for before any of the above: the section names can each be correct and the page still put every claim it makes inside a body, where the outline shows none of them. Report that as one finding about the page rather than as one per buried claim, because the claims are not separately misplaced — the level below them is missing. Name the claims you found and say which sections they fall into.

   A node that groups children names a section at any depth. It is never a finding for promising nothing, and its body is optional: naming a section is the whole job, and the claims are in the children.

   The inverse is a heading over a single line: an outline row and a screenful of whitespace spent on what a bullet would say. Several siblings that each hold one line are one list, and so one finding, not one per heading; name the list they make. The sharpest case is a line that repeats the heading above it as a link to the page of the same name, where the title, the body and the navigation all say one word.

   Never recommend moving a node to another level so that its title fits, and never recommend widening a title until it restates its body. Depth follows the structure, and the title is written to fit the depth.
2. **Where a node sits.** The tree asserts something about every node by where it put it: that these are of one kind, that this one is the exception, that this follows from that. Read each claim against its parent and its siblings and say where the tree asserts something untrue.

   A page's page parent, siblings and child pages are authored structure and are judged the same way as blocks inside a page.

   A heading that does not cover its children. A rule filed under a subject it does not belong to. A node nobody looking for it would look there for, which will be written a second time by whoever failed to find it. A node under a definition rather than under the thing defined.

   This is the category the rest of the report is worth the least without, and it is the one an agent skips, because it cannot be seen in any single body: it needs the parent read, the siblings read, and a guess at who came looking. Name the reader you have in mind when you report one.
3. **What the engine already keeps.** Every node carries its own history, its own `updated_at`, its place in the contents rail and the list of nodes linking to it, so a body repeating any of that goes stale the moment someone edits without touching it. Flag a block documenting its own obsolescence, a "checked in April" stamp, prose listing the sections below, a "back to X" footer.

   A count is the sharpest form of the same fault, because nobody edits a sentence to fix arithmetic: "four page types", "seven languages carry it", where those items are the blocks beneath. The test is where the sentence gets its truth from. From the tree of this page, and it goes; from the subject, the platform or the rule itself, it stays, even where its number happens to match the tree today. A founding year is content, a review date is metadata.

   A block that is mostly a hand-curated list of links is the same fault as an object rather than a sentence: "Contents", "See also", "Quick links". Strip the links and read what is left; if the block becomes nothing, it was navigation. Recommend deletion only after checking the one exception, and recommend deleting a tombstone only after confirming the content it names is live at the destination.

   The exception is what the navigation actually shows, and it shows less than the tree holds: it opens collapsed to the top level, an inner page expands only the path to the root, and on a phone it sits behind the menu button. So a body link to a page below the top level is, for most readers, the only visible way there, and it is not a copy of the navigation. What the tree does settle is reachability: a page reached through its ancestor chain does not need an invented body link merely to exist in the map.

   The home page (`special_role=home`) and every page with child pages are judged by featured navigation, never as ordinary pages of links. They open with what is worth reading below and link a few pages readers come for, even deep ones; those links are their content. Report one that copies the tree by listing its children, one that links only the top-level sections the wanted pages hide under, and a subject it names twice. A full list of children is right only when the reader must choose among all of them, as with ways to install. Flag a facet whose entry page gives the reader no path into its content.
4. **Two places saying one thing.** Not wordiness inside a block, which is lint's, but the same claim carried twice: by a block and its sibling, by a body and the title above it, by a page and the one it was split from. Today it is a repetition; tomorrow one of the two is edited and it is a contradiction, and nobody will know which copy is current.

Wiki-level (judged across the pages in scope, with the outline):

5. **Contradictions across pages.** The same number, date, name, or fact stated differently in two places. This outranks everything else in the report: a reader acts on whichever they met first and never learns the other existed. For fiction or mystifications: the wiki should be internally consistent even when it is consistently making things up. Compare only within the language facet; a fact that reads differently in a page and its translation twin is a translation matter for `wikilayer:translations`, not a contradiction here.
6. **Missed DRY.** A subject treated substantively in several places with no dedicated root page of its own; recommend extracting. Count mentions within the facet only: a page's translation twin is the same mention in another language, not an additional one.
7. **A kinship the tree does not assert.** Among the direct child pages of a page, two or more may belong to one subtopic with no page saying so. The tree currently asserts that they are siblings of everything else beside them, which is the false part; name the unasserted kinship and what a reader loses. Look at sibling title clusters.
8. **The page as one reading.** Judged from the outline: past a couple of dozen rows, or a few screens of body, a reader scrolls rather than reads and the contents rail stops being a map. Neither is a limit and neither decides on its own — a data page of a hundred parallel rows is not the target, and a page carrying several subjects that each stand alone is one at half that size.

   The test is whether a section could be opened cold. One that could is a page wearing a heading; sections that only make sense in sequence mean the page is long but whole, and the repair is to cut rather than to split. Report the weight of each top-level section beside the page total, because a section several times heavier than its siblings is the sharper signal: it is either a subject of its own or a topic whose parts never became child nodes, and saying which of the two it is is the finding.

   Price the split before recommending it: a promoted section stops being met by anyone scrolling its old parent and lives only through a link somebody writes into a body. Say where that link belongs.

   An ancestor chain in the page tree is an inbound route even when the stitched document has no backlinks; flag only pages absent from both the navigation and authored links.

## What a finding must carry

Two things, and a candidate missing either is not a finding.

A citation: the block URL plus the quote, or the list of titles, that demonstrates it. A page reported clean carries a proof-of-work line per block; "looks fine" is not one.

And what goes wrong if it is not applied, said concretely: what becomes false, or what a reader does that they would not have done. "This reads better the other way" is not that. The requirement is what keeps this skill from returning a list of rewordings, which is the failure it is most prone to.

**Report a structural finding as what you read, not as the edit to make.** Renaming, splitting, merging and promoting are the author's calls: they are cheap to apply and expensive to judge, which is the combination that gets a wrong one applied without being weighed. So say what the outline showed you, what the body turned out to hold, and what a reader loses — and stop there. Naming where a node would sit better is part of the observation; handing over a finished title, a split, or a merge to paste in is not, and a finding phrased that way is one the author will apply instead of deciding.

## Order, and what the report is

Report in this order, because it is the order the work is done in, and every category above lands in one of its four steps:

1. a contradiction: two places say different things and a reader acts on whichever they met first;
2. a node where nobody will look for it, or a kinship the tree fails to assert: it will be written a second time by someone who did not find it;
3. a repetition, a body restating what the engine keeps, a page past one reading: each goes wrong on its own, without anybody touching it;
4. everything else this skill found.

The report is observations, not a verdict. Which to act on is the author's call, and a finding refused with a stated reason is as closed as one applied; say this in the report rather than phrasing findings as instructions. What the author must not do is take the cheap end of the list because it is cheap and leave the top of it for later.
translations16 KB

View saved version →

---
name: translations
description: Bring a wikilayer wiki, or one page in it, into translation parity with a target language. Audits cross-language coverage (missing translations, structural divergence, stale translations, possible unlinked twins, links that send a reader into another language), then translates and links the missing pages. A page target fills only that page's subtree, for a page just added or reworked. Unlike the wikilayer lint and review skills this skill writes to the wiki. Use when the user asks to translate a wiki or a single page, fill its missing translations, or check translation parity.
---

# wikilayer:translations

Parity pass across languages. lint and review only advise; this skill also writes: it creates and links the translations a wiki is missing in a target language. It audits first, fills the gaps, and reports the judgment calls for a human rather than forcing them.

## Model

Translations live as parallel nodes in the same wiki, grouped by `link_translation`: a topic has one node per language, all in one group. A wiki's `primary_language` is the source; source nodes carry that language or an empty `language` field. A target-language node is a translation linked into the same group.

Each language has its own front page, in the `home` role for that language; front pages pair by role rather than by a link, and their blocks are linked like any other. The rules page exists only in the primary language and is never translated.

A language is a facet with a life of its own, not a mirror. A target page may hold a block or a link the source does not, and may leave out one the source has. So the skill fills what is missing only where nothing has been written yet, and a link in a target body names a target-language node.

A source node is a **gap** when no node in its group carries the target language. A gap is **filled** when it is a page with no target twin, a block of a page whose target twin this run created, or a block of a page the user named as the target of a page-scoped run. On a whole-wiki run, a missing block on a target page that already existed is reported, not filled: its author may have left it out. Naming the page is the human's decision to fill it.

## Procedure

Hold no page body in the caller: keep only ids, titles, outline rows and subagent reports, and leave reading and translating bodies to subagents.

1. Resolve the target and target language from the user's request (for example "wiki 1 to en", or a URL plus a BCP 47 code). Resolve the wiki with `list_wikis` and take its `primary_language` as the source; never infer it from the outline. If the target or target language is unclear, ask.

   **Scope.** A `wiki` target brings the whole wiki to parity; a `page` target fills only that page's subtree, for example a page just added or reworked. The map comes from the whole wiki; everything else, gaps and reports included, stays inside the scope.
2. Read and accept every rules page the server asks for, and carry the returned signatures on every call they bind. Read them again when a call is refused for them. A translation is a write like any other, so it answers to [what a node holds](https://wikilayer.org/smee-again/wikilayer-howto/54721-pages-and-nodes) and to [wording and marks](https://wikilayer.org/smee-again/wikilayer-howto/54729-wording).
3. Call `get_outline(<wiki-id>, max_depth=0, language=<primary>)`. If its `languages` do not include the target, or it names none, call `add_language` for the target. Without the right to, stop and say so.
4. Read the structural map: `get_outline` at `max_depth=-1` once with `language=<primary>` and once with `language=<target>`, each through every page of results, with `fields=["id","kind","title","special_role","parent_id","depth","sort_key","updated_at"]`.
5. Call `list_translations(wiki_id, node_ids)` over every page and block of both outlines, leaving out the wiki row and the rules page with its subtree. From the answer take:
   - the **map** from each source node to its target twin, the front pages included through `paired_by_role`;
   - the **gaps**: source nodes with no target twin;
   - the **unlinked target pages**: target-language pages in no group. Most are the facet's own; they matter only as possible twins of a gap page under the same parent's twin.
   - **stale pairs**: a target twin whose source has a later `updated_at`.

   When the target outline holds no page or block but its front page, there is nothing to pair: the map is the two front pages and every other source node in scope is a gap, so skip the call.
6. **Term list.** Before any title, settle the run's **term list**: the recurring terms of the source in scope with one target rendering each. A rendering comes from a translation dictionary the wiki or the user names, else from the target-language pages that already exist, else it is chosen once now. The list also settles how the reader is addressed where the target language makes a choice the source does not, such as a formal or informal "you". One subagent builds it: it reads the source pages in scope and the target pages that exist, and returns the list together with any term the target pages already render two ways. Without it, each subagent chooses its own, and one term reads differently from page to page. Hand the list to every subagent of steps 7, 8 and 9, and put the renderings chosen this run, and any term the target pages render two ways, into the report under Review.
7. **Pages first, titles only.** Create every missing target page in scope before any body, so that every body can link a target page that exists. Go by depth; no page is created before its parent's twin. A depth of up to ten pages the caller may title itself; a larger one goes to one subagent, briefed with the source pages' ids, titles and `sort_key`s, their parents' target twins, the unlinked target pages under those twins, the term list, the target language, the wiki id and the signatures. Whoever titles a depth follows the rest of this step. Where an unlinked target page is plainly the same subject as a source page, it creates nothing for it and reports the pair. Otherwise it creates each page with `kind=page`, `language=<target>`, the translated title and the source page's `sort_key`, under the target twin of the source page's parent, or under the wiki root for a top-level source page, and returns the id pairs, target titles and URLs, which go into the map. The caller links every created pair with `link_translation(wiki_id, nodes=[{node_id, other_node_id}, …])`, up to 100 pairs a call, and leaves a reported pair for Decide: a permission check can refuse a subagent the write it lets through for the session that holds the user's request. On a page-scoped run, a source page whose parent twin is missing and outside the scope is reported as a prerequisite and not created; never fall back to the root or another convenient parent.
8. **Then bodies.** Hand each target page in scope to one subagent, the front page included when it is in scope, where it counts as created this run when step 3 added the language; when the scope holds more than ten pages, give pages that share a parent to one subagent together, at most ten to a subagent. Run them one at a time, each after the previous one's report is read and a page of it checked: a flaw in the brief makes no subagent fail, shows only in what it wrote, and repeats in every subagent launched with it. Launch each subagent with an explicitly chosen model, and effort where the client takes one, rather than the session's: translation is judgment, so choose a strong one. Brief each, for every page it gets, with the source page id, its target twin, whether it may fill that twin (created this run, or the named page of a page-scoped run), the outline rows of the source page's blocks (id, parent, `sort_key`), the map's page pairs with their target titles and the pairs of this page's blocks, the term list, the target language, the wiki id and the signatures.

   Each subagent:
   - Reads the source page and the target twin with `get_page_markdown`, never by WebFetch of the `.md` URL, which a model can reword. The `<!-- block:N -->` comment above each node is its id; the closing `## Links here` is generated navigation: never translate it, never compare it.
   - On a twin it may fill: writes the translated page lead where the twin has none, and on a front page created this run the translated title and lead, with `update_node`; then creates every missing block with `create_nodes`, a parent before its children, each under the target twin of its source parent and with its source `sort_key`, and a block that other blocks link before the blocks that link it, so their links can name it. On any other twin: writes nothing and lists the source blocks it has no twin of.
   - Translates in the source's own person and mood: where the source addresses the reader or gives instructions, so does the translation, which the neutral voice of [wording](https://wikilayer.org/smee-again/wikilayer-howto/54729-wording) does not override; and where it states how a thing is, so does the translation: the sentence asserts the same about the same thing, never turned into what someone does with it or into an instruction. Weaves links onto nouns, keeps blockquotes, and mirrors the source node's title and body without summarizing or expanding. Code stays as it is, but natural-language text shown in a code block, such as a prompt the reader pastes or an example outline, is translated. Where the translation outgrows a node's length limit, it shortens wording and never drops a sentence, a link or code.
   - Renders every term on the run's term list with the list's rendering, inflected as the sentence needs, and addresses the reader as the list says.
   - Points every `page:N` and `block:N` it writes at the target twin: from the map, else from the blocks it created itself, else from `list_translations` on that node. `page:home` and `page:rules` stay as written. A link whose node has no twin yet keeps the source id, as when two blocks link each other or the linked block is created in the same call; step 10 repoints it.
   - Punctuates by the target language's own conventions, never by the source's. Restraint with the em-dash is an English convention: German sets off an aside with one freely, and Russian requires one between subject and predicate when the copula is absent. Those are examples, not the list.
   - Compares the twin's blocks with the source's and lists diverging titles and blocks out of source order. It does not list target-only blocks.
   - Returns, for each page: the page URL; created nodes as source-to-target id pairs with URLs; the twin's id if it wrote that twin's lead or title; the renderings it chose for terms the list lacks, each with the ids of the nodes that use it; blocks it found missing or diverging; anything it did not touch, with one-line reasons.

   When they return, link every created pair in batches of up to 100 with `link_translation`, as in step 7. Then reconcile those renderings: where two subagents rendered one term differently, choose one, hand the nodes that use the other to a subagent that rewrites them with `update_node`, inflecting as each sentence needs, and add every rendering chosen here, the reconciled ones included, to the report under Review.
9. **Then proofreading, which no run skips.** A translator does not hear its own calques, so the nodes this run wrote, the pages and blocks of steps 7–8 and each lead or title step 8 wrote, go to a subagent that translated none of them, at most ten pages to a subagent, one at a time and with the model chosen as in step 8. Brief it with the source-to-target pairs of those nodes, every rendering settled this run (the term list, the renderings step 8 reconciled and those its subagents chose), the target language, the wiki id and the signatures. For each page it:
   - reads the target page whole with `get_page_markdown` as a native reader of the target language who has not seen the source, and marks every calque in the nodes this run wrote: a phrase that keeps the source's words or construction where the target language says it otherwise, a metaphor carried over word for word, a word used in a sense the target language does not give it. Nodes this run did not write are the facet's own and stay as they are;
   - then reads the source page, to confirm what each marked place means;
   - rewrites each calque in the target language's own words, a body with `patch_node` and a title with `update_node`, by the rules step 8 translates by: the source's person and mood, nothing summarized or expanded, the target language's punctuation, the settled renderings, code as it is, and link targets as they are, since step 10 repoints them. A rewrite keeps what the sentence asserts and what it asserts it about, usually by keeping its subject: a statement about a thing stays one, never turned into a practice someone performs, an instruction, or a nominalization or passive the target language avoids. In Ukrainian, "A link sits on the noun" becomes «Посилання стоїть на іменнику», not «Посилання ставлять на іменник». Where no natural wording keeps the statement, the place stays as it is and goes into the report;
   - returns, for each page, how many places it rewrote with a few examples, and every place it left because a rewrite would change the meaning.
10. **Then the links left behind.** Call `search_nodes(wiki_id, language=<target>, links_across_languages=true, include_ancestors=false)`, with `subtree_id` set to the scope's target twin on a page-scoped run, through every page of results. Each hit's `cross_links` names every other-language target it links and that target's target-language `twin`, if any. In the nodes this run wrote (created in steps 7–8, plus each twin whose lead or title step 8 wrote), repoint every link that has a twin with `patch_node(wiki_id, nodes=[{node_id, replacements: [{old_target, new_target}, …]}, …])`, up to 100 nodes a call; a node the server refuses to retarget leaves the batch and goes into the report. A link without a twin stays and goes into the report. A crossing link in a node this run did not write is not rewritten, because a facet may link where it likes: it goes into the report, saying whether a twin exists.
11. Compare child pages yourself from the two outlines: a target page under a parent other than its source page's parent's twin is a misplaced twin. A top-level source page's twin belongs under the wiki root, not under the target front page. Then aggregate everything into one markdown report, grouped by the categories below, naming every node as a link. Leave translating bodies to the subagents.

## What it fills vs flags

It fills only gaps as defined above. Five situations go to a human, never resolved automatically, because each can be deliberate:

1. **Structural divergence.** A source block missing from a target page it may not fill, a diverging title, a block out of source order, a misplaced page twin. Target-only nodes are a facet's own and are not reported.
2. **Stale translation.** The source changed after its twin was written. Do not re-translate silently.
3. **Possible unlinked twin.** An unlinked target page that is plainly the same subject as a gap page under the same parent's twin; the gap was left unfilled.
4. **Link crossing languages.** A target body links a source-language node: either the target language has no twin of it, or an earlier translation carried the source id across although a twin exists. That facet's reader lands in another language.
5. **Prerequisite.** A page-scoped run could not create a page because its parent's twin is missing outside the scope.

## Severity

- **Filled**: gaps translated and linked this run, each as a link to the new node, with how many calques proofreading rewrote on its page.
- **Review**: structural divergence, stale translations, links crossing languages, prerequisites, the term list's new or conflicting renderings, and the places proofreading left because a rewrite would change the meaning. A human confirms whether the asymmetry is intended.
- **Decide**: possible unlinked twins. A human decides whether to link the pair or translate the gap anyway.

Release notes

Tool hints now say what each tool can do: tools that write to a wiki or read wikis other people publish are marked as reaching the open web, and tools that overwrite or delete content are marked destructive. Adds a get-started skill.

Declared in the saved package. Remote tools may change independently.

Package details

Publisher declarations from the archived package. These are separate from our research and the live service's terms.

Package license
MIT
Package author
Maxim Oranskiy PR Novi Sad
Keywords
See keywords
Getting started skill
./skills/get-started/SKILL.md
Commerce declaration
Does not support commerceThis does not establish whether access is free or paid.
Review scenarios
5 positive · 3 negativeScenario counts, not test results.

Package observed Nov 3, 2026.

Technical details
First seen
Oct 24, 2026 · 12:40 UTC
Last seen
Nov 4, 2026 · 06:00 UTC
Collection status
Collected

plugin_asdk_app_6ac8fd6e621081919d2f6f56a9043b46

Download plugin data (JSON)