Wiki knowledge engine — archivi con schema, wikilink e synth
Il wiki engine dà a ogni archivio tre livelli di istruzione: regole hard enforce dal codice, uno schema prompt per-archivio (linee guida editoriali advisory) e campi strutturati (persona, purpose, scope). Modello mentale: lo schemaPrompt sta al wiki come…
Il wiki engine dà a ogni archivio tre livelli di istruzione: regole hard enforce dal codice, uno schema prompt per-archivio (linee guida editoriali advisory) e campi strutturati (persona, purpose, scope). Modello mentale: lo schemaPrompt sta al wiki come un CLAUDE.md sta al codice di una repo.
Funzione Community. Documento di riferimento operativo per il Wiki Schema Layer (Phase 187, auditato al gate v0.25 — WIKS-01/02, verificato sul codice live). Fonte:docs/WIKI_SCHEMA_LAYER.md(v0.28.1). Righe di provenienza:FACT-CENSUS.mdF-WIKI-1.
Il modello a 3 livelli
| Livello | Natura | Enforcement | Scope |
|---|---|---|---|
| Regole hard | enforce dal codice, incondizionate | validateWritablePath + blocco prompt sempre iniettato | Ogni percorso di scrittura bindato all'archivio |
| schemaPrompt | linee guida editoriali, per archivio | Solo dati + prompt (mai un gate) | Per archivio, opt-in (vuoto = off) |
| Campi strutturati | persona/purpose/scope config-iniettati | Il comportamento esistente di synthesis/orchestrator | Per archivio, invariato |
Regole hard (code-enforced)
Due meccanismi incondizionati, indipendenti da qualsiasi configurazione:
- Guardia filesystem.
validateWritablePath(packages/server/src/utils/archivePath.ts:39-54) rifiuta qualunque target di scrittura fuori da<archiveBase>/wiki/: prima l'anti-traversal (validateArchivePath), poi il check sul prefissowiki/— un target fuori dawiki/produce l'erroreWrite target outside wiki/ directory: <path>. raw_sources/ is immutable.SiacreatePagecheupdatePagelo chiamano prima di ognifs.writeFile. Nessun endpoint scrive sottoraw_sources/: è immutabile per design. - Specchio a livello di prompt.
HARD_RULE_RAW_SOURCES(archiveConfigService.ts:52-53) è un blocco sempre attivo aggiunto a ogni prompt bindato all'archivio: il testo specchia la guardia (raw_sources/ is immutable), così il modello non tenta mai la via fuori dawiki/— e se l'attentasse, il codice garantisce che non atterri nulla.
schemaPrompt (advisory)
Campo di testo libero salvato nel config JSON dell'archivio:
- Schema:
schemaPrompt: z.string().max(10000).optional()suarchiveConfigSchema— chiave additiva, zero migrazioni. 10000 caratteri ≈ ~2500 token. - Validazione: Zod a ogni write (
PUT /api/archives/:id/config); un payload oltre la cap →400 { error: "Invalid config", details.schemaPrompt }. - Read contract:
GET /api/archives/:id/configsu archivio senza riga →200con il config di default ({ rawSourcesImmutable: true }): è il path di hydratation del primo salvataggio; gli archivi con riga restituiscono il blob salvato tale e quale. - Cap all'iniezione: i blob legacy sopra 10000 caratteri vengono troncati all'iniezione con l'annotazione
(truncated at 10000 characters)— le righe legacy non vengono ri-validat* alla lettura. - Advisory per design: il blocco entra come DATO con etichetta advisory esplicita, mai come grant di privilegio da system prompt. Niente sanitizzazione oltre la cap; istruzioni contraddittorie = rischio di qualità accettato, mitigato dai template della UI.
Precedenza
regole hard (codice) > schemaPrompt (advisory) > campi strutturati- Lo
schemaPromptnon può mai scavalcare le regole hard (il prompt lo dichiara; il codice lo garantisce). - In conflitto con i campi strutturati, lo
schemaPromptvince (On conflict with the structured fields (persona, purpose, scope), these guidelines take precedence over them.). - Un archivio senza schemaPrompt si comporta da baseline + regola hard — zero enhancement, zero degradazione (nessuna sezione placeholder nei prompt).
Dove entra il blocco nel prompt
| Seam | dove | note |
|---|---|---|
| Chat orchestrator (non-streaming) | orchestrator.ts:295-302 (runAgent) | regola hard SEMPRE + blocco advisory quando presente |
| Chat orchestrator (streaming) | orchestrator.ts:805-812 (runAgentStreaming) | gemello streaming, stesso ordine |
| Synthesis Pass 4 (decision) | synthesisStages.ts:784-788 | il blocco advisory viaggia sul role SYSTEM; le Pass 1/2 e il judging delle contraddizioni restano undefined |
All'interno del system prompt: dopo il blocco MANDATORY SEARCH RULE, prima del ternario systemPrompt.
wiki_query e wiki_write
I builtin wiki_query e wiki_write sono skill whose execute() non chiama MAI la LLM: la scrittura genera preview deterministici (wikiWriteService.ts contiene zero invocazioni LLM) — l'iniezione per-skill non raggiungerebbe alcun modello: l'unica superficie LLM è il system prompt dell'orchestrator.
rawSourcesImmutable
rawSourcesImmutable: boolean (default true) su archiveConfigSchema è un flag di documentazione, mai un toggle di enforcement: la regola di immutabilità si applica a prescindere dal flag (la guardia validateWritablePath + il blocco sempre-attivo la garantiscono).
Questa guida copre la superficie operativa del motore wiki; l'approfondimento tecnico vive nel post gemello:
Provenance
| Sezione | Fonte |
|---|---|
| Modello a 3 livelli / regole hard | docs/WIKI_SCHEMA_LAYER.md (§ The 3-layer model, § Layer 1) — F-WIKI-1 |
| schemaPrompt / precedenza / seams | docs/WIKI_SCHEMA_LAYER.md (§ Layer 2, § Precedence chain, § Injection seams) |
| Audit | Phase 187 commits; finalized at the v0.25 gate (WIKS-01/02, Phase 194) |
---
Riferimento operativo — Simmetric Chat v0.28.1 (docs aggiornate 2026-10-02, census SHA `aca5b8ff`).