feat(ms-ai-architect): Layer B ingestion-gate — deterministisk adversariell-innhold-skann før skriving/commit (G6 §8 / R6 punkt d, TDD) [skip-docs]
Load-bearing gaten i den to-lags ingestion-sikkerheten: en deterministisk, alltid-på node-skann (unicode/injection/base64, prosa + fenced code blocks) over kandidat skills/**/*.md, wiret inn som sibling til validate-kb-file.mjs ved det ENESTE skrive-chokepunktet — dekker kb-update + generate-skills + fremtidig R7. - lib/adversarial-scan.mjs: ren disposition-kjerne (provenance-tiering + BLOCK/ WARN-matrise). Ortogonal til korrekthets-judgen. - lib/adversarial-detect.mjs: bro til de DELTE llm-security-detektorene (scanForInjection-lexikon + unicode-scanner + base64/entropi) — ingen kopi av lexikonet. Fail-closed hvis llm-security fraværende. - scan-adversarial-content.mjs: CLI (speiler validate-kb-file.mjs); exit 1=BLOCK (aldri skriv), 2=WARN (flagg → menneske), 0=ren. - 30 tester (19 kjerne + 7 CLI + 4 integrasjon mot ekte llm-security). Suite 692/0. Premiss-verifisert mot live kode: research/research-agent skriver ingenting (kun Layer A); R7-judge re-bruker samme create-guard; CLI-scan alene misset injection+base64 for markdown → importerer rene primitiver i stedet.
This commit is contained in:
parent
687a15138e
commit
89dcd80cbc
8 changed files with 770 additions and 14 deletions
|
|
@ -180,14 +180,19 @@ Task(general-purpose, sonnet): "Research + write skill: Multi-Index..."
|
|||
|
||||
1. **Parse kvitteringer** fra agentene
|
||||
2. **Verifiser filer finnes** med Glob
|
||||
3. **Create-guard (OBLIGATORISK — Spor 3 Port 2):** kjør gaten over batchens nye filer:
|
||||
3. **Create-guard (OBLIGATORISK — to sibling-gater):** kjør BEGGE over batchens nye filer:
|
||||
```bash
|
||||
node scripts/kb-update/validate-kb-file.mjs <fil1.md> <fil2.md> ...
|
||||
node scripts/kb-update/scan-adversarial-content.mjs <fil1.md> <fil2.md> ...
|
||||
```
|
||||
Gaten exit-er ≠0 hvis en fil mangler `Source`, ikke er født-verifisert (mangler
|
||||
`Verified`/`Verified by`), eller er en stor fil uten TOC. **En fil som FAIL-er
|
||||
committes IKKE** — logg den i `state.failed` og send den til menneske-gaten. Dette er
|
||||
det som hindrer generatoren i å re-introdusere drift (avhengighet før Spor 1).
|
||||
Kontrakt-gaten exit-er ≠0 hvis en fil mangler `Source`, ikke er født-verifisert (mangler
|
||||
`Verified`/`Verified by`), eller er en stor fil uten TOC. **Layer B ingestion-gaten
|
||||
(G6 §8 / R6 punkt d)** exit-er 1 (BLOCK — aldri committ, karantene) på adversarielt
|
||||
innhold (unicode/injection/base64 i prosa + fenced code blocks, via delte llm-security-
|
||||
detektorer) eller 2 (WARN — flagg for operatør, ikke auto-committ). **En fil som FAIL-er
|
||||
noen av gatene committes IKKE** — logg den i `state.failed` og send den til menneske-
|
||||
gaten. Dette hindrer generatoren i å re-introdusere drift (kontrakt) OG i å persistere en
|
||||
forgiftet referansefil (Layer B — ortogonal til korrekthet).
|
||||
4. **Oppdater state.json:**
|
||||
- Legg til ferdige (gate-PASS) skill-IDer i `completed`
|
||||
- Legg til feilede/gate-FAIL i `failed`
|
||||
|
|
@ -209,15 +214,17 @@ Task(general-purpose, sonnet): "Research + write skill: Multi-Index..."
|
|||
Gjenstår: N skills
|
||||
```
|
||||
|
||||
2. **Create-guard FØR commit (OBLIGATORISK):** kjør gaten over ALLE filer du er i ferd
|
||||
med å committe. Bare gate-PASS-filer skal med:
|
||||
2. **Create-guard FØR commit (OBLIGATORISK — begge gater):** kjør BEGGE over ALLE filer du er
|
||||
i ferd med å committe. Bare filer som passerer BEGGE skal med:
|
||||
```bash
|
||||
node scripts/kb-update/validate-kb-file.mjs $(git diff --name-only --diff-filter=AM -- 'skills/ms-ai-*/references/**/*.md')
|
||||
FILES=$(git diff --name-only --diff-filter=AM -- 'skills/ms-ai-*/references/**/*.md')
|
||||
node scripts/kb-update/validate-kb-file.mjs $FILES
|
||||
node scripts/kb-update/scan-adversarial-content.mjs $FILES # Layer B ingestion-gate (G6 §8)
|
||||
git add skills/ms-ai-*/references/<dirs>/ scripts/skill-gen/state.json
|
||||
git commit -m "docs(architect): generate N knowledge skills (category-names)"
|
||||
```
|
||||
Hvis gaten exit-er ≠0: IKKE commit de feilende filene — fjern dem fra staging og send
|
||||
til menneske-gaten.
|
||||
Hvis noen av gatene exit-er ≠0: IKKE commit de feilende filene — fjern dem fra staging og
|
||||
send til menneske-gaten (kontrakt-FAIL rettes; Layer B BLOCK karantenes/adjudiseres).
|
||||
|
||||
3. **Oppdater STATE.md** med ny status
|
||||
|
||||
|
|
@ -316,7 +323,7 @@ status: success|no_changes|failed
|
|||
```
|
||||
|
||||
4. Track in `state.json` under a new `"updated"` array
|
||||
5. **Create-guard (OBLIGATORISK):** `node scripts/kb-update/validate-kb-file.mjs <oppdaterte filer>` — gate-FAIL committes IKKE
|
||||
5. **Create-guard (OBLIGATORISK — begge gater):** `node scripts/kb-update/validate-kb-file.mjs <oppdaterte filer>` + `node scripts/kb-update/scan-adversarial-content.mjs <oppdaterte filer>` (Layer B ingestion-gate, G6 §8) — FAIL på noen av dem committes IKKE
|
||||
6. After each batch, verify files still pass `validate-plugin.sh`
|
||||
|
||||
**Key difference from generation:** Update uses Edit (preserves structure), generation uses Write (creates from scratch).
|
||||
|
|
|
|||
|
|
@ -131,7 +131,11 @@ d. **For `approved`:** registrér URLen i `url-registry` (gated) så den fanges
|
|||
4. `validateKbFile(content)` MÅ være `valid: true` (title + Last updated + Status + Source + **Verified + Verified by**; **store filer også TOC**) før noe gates videre (ellers be modellen fylle manglende felt).
|
||||
5. For hver status-/load-bearing-påstand: `buildChange({...})` → **lag 5** `classifyChange(...)` (samme gate som §4 c2). Status-påstander er alltid `flagged`.
|
||||
6. `resolveTargetPath(tax, category, filename)` → eierskill-sti via taksonomien (`null` = ukjent kategori → flagg for operatør, ikke skriv).
|
||||
7. **Create-guard FØR skriving:** `node scripts/kb-update/validate-kb-file.mjs <sti>` (exit ≠0 ⇒ ikke skriv). Først etter operatør-gate + grønn create-guard: atomisk skriving (`lib/atomic-write.mjs` + `lib/backup.mjs`). **`transform.mjs` skriver aldri selv** — verifisert av `tests/kb-update/test-transform.test.mjs` (import-invariant). Kriterium verifisert av `tests/kb-eval/test-transform-criterion.test.mjs` (regenerer 1 fil → eval ≥ baseline).
|
||||
7. **Create-guard FØR skriving (to sibling-gater):** kjør BEGGE (exit ≠0 på noen av dem ⇒ ikke skriv):
|
||||
- `node scripts/kb-update/validate-kb-file.mjs <sti>` — kontrakt (Source/født-verifisert/TOC).
|
||||
- `node scripts/kb-update/scan-adversarial-content.mjs <sti>` — **Layer B ingestion-gate (G6 §8 / R6 punkt d):** deterministisk adversariell-innhold-skann (unicode/injection/base64, prosa + fenced code blocks) via de delte llm-security-detektorene. **exit 1 = BLOCK** (aldri skriv — karantene, operatør adjudiserer); **exit 2 = WARN** (flagg → samme menneske-i-loop som en status-påstand; ikke auto-committ). Gaten er ortogonal til korrekthets-judgen: en faktakorrekt men forgiftet fil blokkeres likevel.
|
||||
|
||||
Først etter operatør-gate + BEGGE create-guards grønne: atomisk skriving (`lib/atomic-write.mjs` + `lib/backup.mjs`). **`transform.mjs` skriver aldri selv** — verifisert av `tests/kb-update/test-transform.test.mjs` (import-invariant). Kriterium verifisert av `tests/kb-eval/test-transform-criterion.test.mjs` (regenerer 1 fil → eval ≥ baseline). Layer B verifisert av `tests/kb-update/test-adversarial-scan.test.mjs` + `test-scan-adversarial-content.test.mjs` + `test-adversarial-detect-integration.test.mjs`.
|
||||
|
||||
e. **Invariant:** `discover-new-urls.mjs` (deteksjon) skriver **aldri** ledgeren — den kun leser. Bare denne gaten skriver. Verifisert av `tests/kb-update/test-discover-invariant.test.mjs`.
|
||||
|
||||
|
|
@ -186,13 +190,15 @@ c2. **Verifisering-ut (lag 5) — FØR du skriver.** Hver kandidat-endring fra (
|
|||
- **Adversarial motbevis-panel (LLM-runtime):** for status-/load-bearing-påstander, kjør et lite panel som *prøver å motbevise* `new_value` mot den utpekte `authority_source`, og mat resultatene inn som `refutations[]` (`[{refuted, reason}]`). Multi-agent foreslås når lag 4/5 kjøres i produksjon (roadmap §71).
|
||||
- **Invariant:** `verify-out.mjs` skriver aldri — den returnerer kun en verdict. Selve skrivingen skjer i (d), gated. Verifisert av `tests/kb-update/test-verify-out.test.mjs`.
|
||||
d. **Oppdater fila:** `Edit` med endringer som er `auto-applied` eller eksplisitt godkjent av operatør i (c2). Behold "For Cosmo"-seksjonen og overordnet struktur. Oppdater `Last updated: YYYY-MM-DD`-header til dagens dato. **Lag-4-kontrakt:** kjør `validateKbFile(<ny fil-innhold>)` (`lib/transform.mjs`) før skriving — den skal være `valid: true`. Mangler fila et `**Source:**`-header, legg det til i header-blokka med den utpekte autoritets-URLen for hovedkilden — da fanger lag 3 (`resolveAuthority` + `build-registry`) den som `authority_source`, og lag-5 regel 3 blir virksom for fila. Mangler en **stor fil (>100 linjer)** en `## Innhold`-TOC, generer den med `buildToc(<brødtekst>)` og legg den inn rett etter header-`---` — `validateKbFile` krever den nå for store filer, så in-place-oppdateringer backfiller TOC inkrementelt (Fase 1c).
|
||||
e. **Committ:** `git add <fil>` + `git commit -m "chore(ms-ai-architect): refresh KB $(basename <fil>) [skip-docs]"` med mindre `--single-commit` ble gitt
|
||||
d1. **Layer B FØR skriving/commit (ingestion-gate, G6 §8):** kjør `node scripts/kb-update/scan-adversarial-content.mjs <fil>` på den oppdaterte fila. exit 1 (BLOCK) ⇒ ikke skriv/committ — karantene, operatør adjudiserer; exit 2 (WARN) ⇒ flagg for operatør, ikke auto-committ. Deterministisk adversariell-innhold-skann via delte llm-security-detektorer; ortogonal til korrekthets-gatene i (c1/c2).
|
||||
e. **Committ:** kjør create-guardene (`validate-kb-file.mjs` + `scan-adversarial-content.mjs`) grønne på fila, deretter `git add <fil>` + `git commit -m "chore(ms-ai-architect): refresh KB $(basename <fil>) [skip-docs]"` med mindre `--single-commit` ble gitt
|
||||
|
||||
### 5. Single-commit modus
|
||||
|
||||
Hvis `--single-commit`: skip committer per fil, og lag én samlet commit til slutt:
|
||||
Hvis `--single-commit`: skip committer per fil, og lag én samlet commit til slutt. **Layer B FØR commit (ingestion-gate, G6 §8):** skann alle endrede `skills/**/*.md` — en BLOCK (exit 1) tas ut av staging (aldri committet, karantene); en WARN (exit 2) flagges for operatør før commit:
|
||||
|
||||
```bash
|
||||
node scripts/kb-update/scan-adversarial-content.mjs $(git diff --name-only --diff-filter=AM -- 'skills/**/*.md')
|
||||
git add skills/
|
||||
git commit -m "chore(ms-ai-architect): refresh KB — N files [skip-docs]"
|
||||
```
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue