Commit graph

527 commits

Author SHA1 Message Date
e9e5ceebfb feat(llm-security): playground v7.6.0 fase 5e-h — Tier 3 spesialkomponenter (del 2) [skip-docs]
- top-risks + top-risk: rangert top-funn-listing per rapport
  (renderTopRisks helper, integrert i renderScan, renderDeepScan,
  renderPluginAudit, renderPosture, renderAudit — ekskluderer info-funn,
  default 5 toppfunn med data-severity-tinted left-border)
- recommendation-card: data-severity-attributtet utvidet på alle
  inline-bruk (Trust-verdict, Quick wins, Action plan tiers, Vilkår)
  pluss /security clean (per-bucket advisory-cards) og /security harden
  (intro snapshot + per-recommendation diff-cards med action-type-mapping
  CREATE→positive / APPEND→medium / MERGE→low / SKIP→low)
- risk-meter: lagt til på renderDeepScan og renderAudit conditional på
  data.risk_score — utvider eksisterende bruk (renderScan, renderPluginAudit,
  renderRedTeam) til 5 archetypes
- card--severity-{level}: severity-color border-modifier på .findings__item
  i renderFindingsBlock (delt helper) pluss inline-bruk i renderAudit
  category-cards og renderDiff row-items

Ny helper-funksjon mapSeverityToCardLevel(input) normaliserer severity-
strenger og action-types til DS Tier 3-konvensjonene
(critical/high/medium/low/positive). renderRecommendationsList får valgfri
severity-param som default fall-back til 'low'.

Verifisering bekreftet:
- top-risks: 5 forekomster (≥1 ✓)
- recommendation-card: 32 (≥1 ✓ — utvidet fra 4)
- risk-meter: 7 (≥3 ✓ — 5 archetypes bruker helper)
- card--severity-: 4 (≥4 ✓ — findings__item + 2 inline-steder)
- Sesjon 2-3 anker intakte (verdict-pill-lg 20, fp-step 12,
  badge--scope-security 5, tfa-flow 3, mat-ladder 2, suppressed-group 8,
  codepoint-reveal 12)
- Window-globaler intakt
- JS parse: OK (node --check på ekstrahert main JS)
- demo-state JSON parse: OK (3 prosjekter, 18 rapporter)
- HTML-balanse: 3 script / 3 /script / 1 style
- Smoke-test mot demo-data: 5/7 renderere viser komplett markup;
  renderDeepScan og renderAudit har tomme findings-arrays i demo så
  top-risks/card--severity rendrer korrekt tomt (defensiv design,
  bevisst per Sesjon 3 observasjon 2)

Filendring: 10545 → 10677 linjer (+132 netto).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 14:00:04 +02:00
fbda041522 feat(llm-security): playground v7.6.0 fase 5a-d — Tier 3 spesialkomponenter (del 1) [skip-docs]
Integrer fire llm-security-spesifikke Tier 3-komponenter:
- tfa-flow + tfa-leg + tfa-arrow: visualiserer lethal-trifecta-kjede
  i toxic-flow-rapport (untrusted-input → sensitive-access → exfil-sink)
- mat-ladder + mat-step: posture-modenhet over kategorier i posture-rapport
- suppressed-group: narrative-audit (v7.1.1) i scan-rapport executive summary
- codepoint-reveal + cp-tag: side-ved-side reveal for Unicode-steganografi
  i mcp-inspect-rapport (visible vs decoded)

Endringer:
- Fire nye render-helpers (renderToxicFlow, renderMatLadder,
  renderSuppressedGroup, renderCodepointReveal) i hovedscriptet, plassert
  før renderScan/Deep/Posture/MCP-Inspect.
- parseScan + parseDeepScan utvidet med narrative_audit-felt via ny
  parseNarrativeAudit-helper som ekstraherer "**Suppressed signals:**"-
  blokken fra raw_markdown.
- renderScan: meterHtml + suppressedHtml + toxicHtml + owaspHtml + ...
- renderDeepScan: suppressedHtml + toxicHtml + smHtml + matrixHtml + ...
- renderPosture: overall + ladderHtml + smHtml + quickHtml + ...
- renderMcpInspect: invHtml + cpHtml (rebuilt via renderCodepointReveal)

Verifisert:
- tfa-flow=3, mat-ladder=2, suppressed-group=8, codepoint-reveal=12 i HTML
- verdict-pill-lg=20, fp-step=12, scope-security=5 (Sesjon 2-kriterier intakte)
- form-progress__step strict singular=0 (DS canonical bevart)
- Window-globaler intakt (24 unike __-prefiksede globaler)
- JS parse OK (node --check), JSON-state parse OK (3 prosjekter, 18 rapporter)
- HTML-balanse OK (3 script-tags, 1 style-blokk)
- Smoke-test mot demo-data: alle 4 helpers rendrer non-empty HTML med
  forventede DS-klasser

Master-plan: plugins/llm-security/playground/V7.6.0-PLAN.local.md (Sesjon 3 av 5).
Sesjon 4 (fase 5e-h: top-risks, recommendation-card, risk-meter, card--severity-*)
neste, deretter Sesjon 5 (verifisering, docs, release).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 13:25:35 +02:00
2481133515 feat(llm-security): playground v7.6.0 fase 3-4 — scope-identitet + Tier 3 form-progress [skip-docs]
Fase 3: badge--scope-security som identitets-chip på alle prosjekt- og
rapport-cards (signal "denne er llm-security"). Plassert i topbar
(app-header__brand), fleet-tile-meta, command-subcard card__head,
catalog-card card__head, og onboarding form-progress autosave-blokk.
verdict-pill-lg (DS Tier 2 + Tier 3 supplement) erstatter custom
verdict-pill — nå med __verdict + valgfri __sub-struktur. renderPageShell
aksepterer opts.verdictSub som videresendes til renderVerdictPill.

Fase 4: Onboarding wizard bruker DS Tier 3 form-progress + fp-step med
data-state="done|in-progress|pending" og __num/__name — erstatter
playground-ens lokale form-progress__step-implementasjon. Steps wrappet
i form-progress__steps-container per DS-mønster. Aside har nå
form-progress__autosave-blokk med scope-badge og fullført-counter.

CSS-blokken som tidligere overstyrte DS for .verdict-pill og
.form-progress__heading/__step/__step-marker/--done er fjernet —
DS Tier 3 supplement vinner cascade-en.

Verifisering: verdict-pill-lg=20 (>=12), badge--scope-security=5 (>=5),
fp-step=12 (>=5), .verdict-pill\b i style-blokk=0, form-progress__step
strict singular=0 (3 naive treff er DS-canonical __steps-plural).
14 window-globaler intakt. JS parse OK, demo-state JSON OK,
HTML-balansert (3/3 script, 1/1 style).

Sesjon 2 av 5 i v7.6.0-pipeline. Foundation (sesjon 1) ga 9ef0c48.
Neste: Tier 3 spesialkomponenter del 1 (fase 5a-d) i sesjon 3.
Docs (plugin README/CLAUDE/rot-README/CHANGELOG) oppdateres i Sesjon 5
per master-plan; derav [skip-docs] her.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 13:13:03 +02:00
9ef0c48c00 feat(llm-security): playground v7.6.0 fase 1-2 — fjern DS-duplikater + page-shell harmonisering
Slett ~50 duplikat-CSS-deklarasjoner fra playground-ens <style>-blokk
som overstyrte DS Tier 3 supplement uten gevinst (.app-shell, .tab-list,
.fleet-tile*, .form-progress, .eyebrow, .page__*, .key-stat*, .field-*,
.expansion (ekskl. body), .stack-*, .card*, .tracks*, .checkbox-row).

JS-fix: 4 modifier-strenger oppdatert fra forkortede ('crit', 'med')
til DS-konsistente fulle navn ('critical', 'medium') i renderKeyStatsGrid-data.

Konsekvens: DS vinner cascade-en, eliminerer subtile visuelle drift
mellom playground og referanse-scenarioer.

Page-shell harmonisering: alle 4 overflater (onboarding, home, catalog,
project) bruker nå DS page__header-klyngen via renderPageShell. Onboarding
konvertert fra custom <header class="onboarding-header"> til samme mønster.
renderPageShell utvidet med opts.meta (page__meta) og opts.hero
(page__header--hero modifier). Hero-mønster på home med
clamp(36px, 5vw, 56px) og letter-spacing -0.025em.

Behold til Sesjon 2: .verdict-pill (erstattes av verdict-pill-lg fase 3),
.form-progress__step* (erstattes av fp-step fase 4), .multi-select
(bevisst input-box-look), .expansion__body (markup-mismatch m/ DS-anim).

Forberedelse til v7.6.0 — Tier 3 referanse-case.
2026-05-06 12:55:25 +02:00
ce3891bdd0 feat(llm-security): playground Fase 3 — v7.5.0 med 18 parsere/renderere
Single-file SPA playground har nå parser + renderer for alle 18
produces_report=true-kommandoer (Fase 2: 10 høy-prio + Fase 3: 8
gjenstående: mcp-inspect, supply-check, pre-deploy, diff, watch,
registry, clean, threat-model). 18 markdown test-fixtures fungerer
som kontrakt-anker for parser-utvikling.

Komplett demo-prosjekt `dft-komplett-demo` har alle 18 rapporter
ferdig parsed inline — klikk-gjennom uten "parser ikke implementert"-
paneler. 2 nye archetypes i KEY_STATS_CONFIG: kanban-buckets (clean)
og matrix-risk (threat-model).

Bug-fix: normalizeVerdictText sjekker nå GO-WITH-CONDITIONS /
CONDITIONAL / BETINGET FØR plain GO så betinget verdict (pre-deploy
med åpne vilkår) ikke kollapser til ALLOW.

Eksponert 11 window-globaler for testing/automasjon (__store,
__navigate, __loadDemoState, __PARSERS, __RENDERERS, __CATALOG,
__inferVerdict, __inferKeyStats, __renderPageShell,
__handlePasteImport, __scheduleRender). 12 Playwright-genererte
screenshots i playground/screenshots/v7.5.0/.

A11Y-rapport (WCAG 2.1 AA): 0 blokkerende, 3 mindre forbedringer
flagget for v7.5.x patch (skip-link, heading-hierarki på project,
aria-live toast).

Versjonsbump 7.4.0 -> 7.5.0 i 10 filer (package.json, plugin.json,
CLAUDE.md header, README badge, CHANGELOG-entry, 3 scanner VERSION-
konstanter, ROADMAP, marketplace-rot README).

Ingen scanner- eller hook-behavior-changes — purely additive surface.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 22:15:47 +02:00
c71d7030e7 Add .mailmap to consolidate author identities 2026-05-05 20:08:12 +02:00
fba0adf17c feat(llm-security): playground Fase 1 — single-file SPA skjelett [skip-docs]
Mirror av ms-ai-architect playground-arkitektur, tilpasset llm-security:

- 4 overflater (onboarding/home/catalog/project) med surface-router
- IndexedDB persistens (llm-security-playground-v1) + localStorage fallback
- Theme-bootstrap med FOUC-prevention og localStorage-persist
- 20 kommandoer i CATALOG (5 kategorier: discover/posture/findings-ops/
  hardening/adversarial/mcp-ops) med full input_fields + report_archetype
- 5-gruppers onboarding (organisasjon/scope/profil/plattform/compliance)
  med form-progress sidebar
- Home: 3 tracks + fleet-grid prosjektliste + tom-state med demo-data
- Katalog: ekspanderbare grupper med live-søk og forhåndsvisning
- Prosjekt-stub: 4 screen-tabs + 6 kategori-tabs + per-kommando
  skjema/paste-import/rapport-soner
- Demo-state: Direktoratet for digital tjenesteutvikling med 2 prosjekter
- Eksport/import (JSON envelope), action-handlers (35), modal-portal

PARSERS + RENDERERS er tomme routing-objekter — fylles i Fase 2 (10 høy-prio
kommandoer) og Fase 3 (resterende 10). Paste-import viser «parser ikke
implementert»-guide-panel for kommandoer uten parser, og lagrer rå markdown
i state for fremtidig parsing.

Vendor: 27 filer synket fra shared/playground-design-system/
(MANIFEST.json sjekksum-låst, source_commit 487f7ae).

Verifisert: node --check OK (2737 linjer, 113733 char inline JS),
HTML-tag-balanse OK. Manuell smoke-test gjenstår.

Docs (plugin README, CLAUDE.md, rot-README) bumpes ved Fase 3-fullføring
sammen med plugin.json v7.5.0. Derfor [skip-docs] her.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 18:47:45 +02:00
487f7ae746 chore(voyage): scrub ultra-cc-architect references from source
The ultra-cc-architect plugin was removed from the marketplace; voyage's
architecture-discovery contract still pointed at it by name. Replaced
verbatim references with plugin-agnostic phrasing ("upstream architect
producer") in code comments and user-facing warning messages.

CHANGELOG entries and config-audit v5.0.0 snapshots intentionally
preserved as historical records.
2026-05-05 15:51:17 +02:00
cbbd1b0589 docs: README — bump llm-security to v7.4.0 with examples + e2e suite
- Add v7.4.0 line covering 9 runnable examples and 3 new e2e test suites
- Update test count 1768 → 1822 in stat footer
- Add "9 runnable examples" to stat footer
2026-05-05 15:43:54 +02:00
7a90d348ad feat(voyage)!: marketplace handoff — rename plugins/ultraplan-local to plugins/voyage [skip-docs]
Session 5 of voyage-rebrand (V6). Operator-authorized cross-plugin scope.

- git mv plugins/ultraplan-local plugins/voyage (rename detected, history preserved)
- .claude-plugin/marketplace.json: voyage entry replaces ultraplan-local
- CLAUDE.md: voyage row in plugin list, voyage in design-system consumer list
- README.md: bulk rename ultra*-local commands -> trek* commands; ultraplan-local refs -> voyage; type discriminators (type: trekbrief/trekreview); session-title pattern (voyage:<command>:<slug>); v4.0.0 release-note paragraph
- plugins/voyage/.claude-plugin/plugin.json: homepage/repository URLs point to monorepo voyage path
- plugins/voyage/verify.sh: drop URL whitelist exception (no longer needed)

Closes voyage-rebrand. bash plugins/voyage/verify.sh PASS 7/7. npm test 361/361.
2026-05-05 15:37:52 +02:00
8f1bf9b7b4 chore(llm-security): v7.4.0 — examples + e2e suite minor
Bumps from v7.3.1 to v7.4.0. Purely additive surface — no scanner
or hook behavior changes, no breaking changes.

Headline content (already merged on main since v7.3.1):

- examples/ utvidelse — seven runnable demonstration walkthroughs
  shipped over three sessions (sesjon 1 pre-existing
  prompt-injection-showcase + lethal-trifecta-walkthrough,
  mcp-rug-pull, supply-chain-attack, poisoned-claude-md,
  bash-evasion-gallery, toxic-agent-demo, pre-compact-poisoning).
  Each is self-contained: README + fixture + run-script +
  expected-findings testable contract. State-isolation pattern
  (PID-suffixed JSONL or env-overrides like
  LLM_SECURITY_MCP_CACHE_FILE) keeps the user's real cache and
  /tmp state untouched.
- tests/e2e/ — three new suites totalling 45 tests:
  attack-chain.test.mjs (17), multi-session.test.mjs (9),
  scan-pipeline.test.mjs (19). Test count 1777 to 1822. These
  exercise the framework as a coordinated system rather than as
  isolated unit-tests.

Version sync (8 files):

- package.json
- .claude-plugin/plugin.json
- CLAUDE.md (header)
- README.md (badge + Recent versions tabellen new row)
- CHANGELOG.md (Unreleased to [7.4.0] - 2026-05-05 with summary)
- scanners/dashboard-aggregator.mjs VERSION constant
- scanners/ide-extension-scanner.mjs VERSION constant
- scanners/posture-scanner.mjs VERSION constant

Stabilization-stance unchanged. v8.0.0 remains the planned
deprecation-cleanup release. v7.x continues as the stable line.

Tests: 1822/1822 grønne lokalt etter bump.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 15:34:02 +02:00
e89ac5eb98 fix(voyage): verify.sh handles v4.0.0 reality (URL exception + --local flag) [skip-docs] 2026-05-05 15:27:11 +02:00
ee56b11c78 feat(voyage)!: bump v4.0.0, rename plugin to voyage, CHANGELOG entry [skip-docs] 2026-05-05 15:27:06 +02:00
7684672ca3 feat(voyage)!: add verify.sh automating brief SC1-SC7 [skip-docs] 2026-05-05 15:23:26 +02:00
1e5838146f feat(voyage)!: add TRADEMARKS.md disclaiming Anthropic affiliation [skip-docs] 2026-05-05 15:23:26 +02:00
b6d912200e feat(llm-security): add pre-compact-poisoning example for PreCompact hook [skip-docs]
Runnable demonstration of hooks/scripts/pre-compact-scan.mjs (the
only PreCompact hook in the plugin) detecting both a CRITICAL
injection pattern and an AWS-shaped credential inside a synthetic
JSONL transcript, exercised across all three values of
LLM_SECURITY_PRECOMPACT_MODE plus a benign-transcript control case
in block mode that proves the gate is not a brick wall.

The transcript is generated at runtime in a per-invocation tempdir
under os.tmpdir() and the directory is removed in a finally block,
so the user's real ~/.claude/projects/.../transcripts/ are never
touched. The AWS-shaped key uses the same 'AK' + 'IA' + ...
fragmentation idiom as tests/e2e/attack-chain.test.mjs so this
source contains no literal credentials and pre-edit-secrets does
not block writes during development.

Nine independent assertions (9/9 must pass):
- block mode + poisoned: exit 2, decision=block JSON, reason text
  covers both injection and AWS labels (3 assertions)
- warn mode + poisoned: exit 0, systemMessage JSON, no decision
  field (2 assertions)
- off mode + poisoned: exit 0, no JSON on stdout (2 assertions)
- block mode + benign: exit 0, no decision=block JSON (2 assertions)

OWASP / framework mapping: LLM01, LLM02, ASI01, AT-1, AT-3.

Docs updated: plugin README "Other runnable examples", plugin
CLAUDE.md "Examples" tabellen, CHANGELOG [Unreleased] Added.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 15:23:10 +02:00
92fb0087fa feat(llm-security): add toxic-agent-demo example for TFA scanner [skip-docs]
Single-component lethal-trifecta walkthrough that drives
scanners/toxic-flow-analyzer.mjs against a deliberately
misconfigured fixture plugin. The fixture agent declares
tools: [Bash, Read, WebFetch], which alone covers all three
trifecta legs (input surface + data access + exfil sink). No
hooks/hooks.json is shipped, so TFA's mitigation logic finds
no active guards and emits a CRITICAL "Lethal trifecta:"
finding without downgrade.

Plugin marker is plugin.fixture.json (recognised by isPlugin())
rather than .claude-plugin/plugin.json — the latter is blocked
by the plugin's own pre-write-pathguard hook, and
plugin.fixture.json exists in isPlugin() specifically so
example fixtures can self-mark without touching guarded paths.

Three independent assertions (3/3 must pass): direct trifecta
present and CRITICAL; finding mentions the exfil-helper
component; description confirms "no hook guards detected"
(proves the mitigation path stayed inactive). expected-findings.md
documents the contract.

OWASP / framework mapping: ASI01, ASI02, ASI05, LLM01, LLM02, LLM06.

Docs updated: plugin README "Other runnable examples", plugin
CLAUDE.md "Examples" tabellen, CHANGELOG [Unreleased] Added.
[skip-docs] is appropriate because examples don't change what
the plugin "synes å dekke utad" — marketplace root README is
unaffected.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 15:15:04 +02:00
15607b182e feat(voyage)!: collapse MIGRATION.md to v3->v4 rebrand notice [skip-docs] 2026-05-05 15:14:47 +02:00
14ecda886c feat(voyage)!: bulk content rewrite ultra -> voyage/trek prose [skip-docs]
Sed-pipeline (16 patterns, longest-match-first) sweeper residuelle ultra*-treff
i prose, command-narrativ, agent-prompts, hook-kommentarer, doc-prosa.

Pipeline-utvidelser fra V4-prompten:
- BSD-syntax [[:<:]]ultra[[:>:]] istedenfor \bultra\b (BSD sed mangler \b)
- 6 compound-patterns for ultraplan/ultraexecute/ultraresearch/ultrabrief/
  ultrareview/ultracontinue uten -local-suffiks
- ultra*-stats glob -> trek*-stats glob
- Linje-eksklusjon redusert til ultra-cc-architect (Q8); session-state-
  eksklusjonen var over-protektiv
- File-eksklusjon utvidet til settings.json, package.json, plugin.json,
  hele .claude/-treet (gitignored + V5-territorium)

Q8-undantak holdt: architecture-discovery.mjs + project-discovery.mjs urort.
Filnavn-konvensjon holdt: .session-state.local.json + *.local.* preservert.

Manuell narrative-fix: tests/lib/agent-frontmatter.test.mjs linje 10
mangled "/ultra*-local" til "/voyage*-local" (ingen slik kommando finnes);
korrigert til "/trek*".

Residualer utenfor scope (V5 handterer): package.json + .claude-plugin/
plugin.json (Step 12-14 versjons-bump). .claude/* er gitignored
spec-historikk med tilsiktet BEFORE/AFTER-narrativ.

Part of voyage-rebrand session 3 (Wave 4 / Step 10).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 15:08:20 +02:00
ca5a8cec67 feat(llm-security): add 3 more runnable threat examples [skip-docs]
Three new self-contained, runnable threat demonstrations under
examples/, continuing the batch started in 583a78c. Each example
has README.md + run-*.mjs + expected-findings.md and uses
state-isolation discipline so the user's real cache/state files
are never polluted.

- examples/supply-chain-attack/ — two-layer demonstration:
  pre-install-supply-chain (PreToolUse) blocks compromised
  event-stream version 3.3.6 and emits a scope-hop advisory for
  the @evilcorp scope; dep-auditor (DEP scanner, offline) flags
  5 typosquat dependencies plus a curl-piped install-script
  vector in the fixture package.json. Maps to LLM03/LLM05/ASI04.

- examples/poisoned-claude-md/ — all 6 memory-poisoning detectors
  fire on a deliberately poisoned CLAUDE.md plus a fixture
  agent file under .claude/agents (E15/v7.2.0 surface):
  detectInjection, detectShellCommands, detectSuspiciousUrls,
  detectCredentialPaths, detectPermissionExpansion,
  detectEncodedPayloads. No agent runtime needed — scanner
  imported directly. Maps to LLM01/LLM06/ASI04.

- examples/bash-evasion-gallery/ — one disguised variant per
  T1 through T9 evasion technique fed through pre-bash-destructive,
  verified BLOCK after bash-normalize strips the evasion. T8
  base64-pipe-shell uses its own BLOCK_RULE. The canonical
  destructive form uses a path token rather than the bare slash
  (regex word-boundary requires it). Source-string fragmentation
  pattern reused from the e2e attack-chain test. Maps to
  LLM06/ASI01/LLM01.

Plugin README "Other runnable examples" section + plugin
CLAUDE.md "Examples" table + CHANGELOG Unreleased/Added
all updated. Marketplace root README unchanged
([skip-docs] for marketplace-level gate — plugin's outward
coverage is unchanged, only demonstrations were added).
2026-05-05 15:01:20 +02:00
8179415bc2 chore(ms-ai-architect): KB refresh complete — 23 files (high batch 2) [skip-docs]
Last batch in HIGH bucket. Combined with 82bd665 (critical 9 + high batch 1, 21 files), this finishes the critical+high KB-refresh sweep for v1.12.0.

Substantive edits (3 files):
- security-copilot-integration.md: M365 E5/E7 inclusion auto-provisioning, agents-first landing experience, role-based onboarding (Verified MCP 2026-05)
- entra-agent-id-zero-trust.md: Ignite 2025-utvidelser — Conditional Access for agenter, Risky agents, 3 nye Agent ID-roller, Microsoft Agent Identity Platform, Copilot Studio blueprint principal
- ai-center-of-excellence-setup.md: Ny "Oppdateringer 2026-05"-seksjon — tre-roller-modell (platform/workload/CoE), agent-ferdighetsområder, sentralisert→rådgivende operasjonsmodell

Date-bump (20 files):
- HIGH-bucket filer der MCP-fetch viste kosmetiske endringer (forrige sesjons lærdom replikert)

Tests: validate-plugin.sh PASS 219.
2026-05-05 14:52:42 +02:00
c407d3451d feat(voyage)!: rename stats filenames, settings keys, hook prefixes [skip-docs]
- lib/stats/event-emit.mjs: STATS_FILENAME -> trekexecute-stats.jsonl + comment
- hooks/scripts/post-bash-stats.mjs: stats target + comment -> trekexecute-stats.jsonl
- lib/stats/cache-analyzer.mjs: help-text + comment -> trekexecute-stats.jsonl
- tests/lib/stats-event-emit.test.mjs (lines 104, 117): fixture assertions
- settings.json: ultraplan/ultraresearch -> trekplan/trekresearch keys + statsFile values
- tests/lib/doc-consistency.test.mjs: allowlist (line 83) + accessor cfg.ultraplan?.* -> cfg.trekplan?.* (lines 91, 93) — atomic-pair, prevents vacuous undefined assertions
- scripts/q3-cache-prefix-experiment.mjs: STATS_JSONL hardcoded path -> voyage data dir + trekexecute filename
- hooks/scripts/pre-bash-executor.mjs (2 lines), pre-compact-flush.mjs (2 lines), pre-write-executor.mjs (1 line): [ultraplan]/[ultraplan-local] stderr prefix -> [voyage]
- commands + agents/review-orchestrator.md + CLAUDE.md: prose stats filename literals -> trek* equivalents

Atomic per session-spec: settings.json scope keys + doc-consistency.test.mjs
allowlist + property accessors committed together to prevent silent vacuous
undefined-equals-undefined assertions.

Part of voyage-rebrand session 2 (W3.7 / Step 9).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 14:49:03 +02:00
583a78c6cc feat(llm-security): add lethal-trifecta + mcp-rug-pull example contents [skip-docs]
Companion to 8df5d5c (which only carried the doc updates — the example
directories themselves were left out of staging by mistake). This
commit adds the actual example mappes:

- examples/lethal-trifecta-walkthrough/{README.md, run-trifecta.mjs,
  expected-findings.md}
- examples/mcp-rug-pull/{README.md, run-rug-pull.mjs,
  expected-findings.md}

Plus plugin CLAUDE.md "Examples (runnable demonstrations)" section
with a 4-row table covering malicious-skill-demo, prompt-injection-
showcase, lethal-trifecta-walkthrough, and mcp-rug-pull plus the
state-isolation discipline notes.

Marketplace root README unchanged since plugin's outward coverage
is unchanged ([skip-docs] covers the marketplace-level gate).
2026-05-05 14:45:39 +02:00
8df5d5c70e feat(llm-security): add lethal-trifecta + mcp-rug-pull examples [skip-docs]
Two new self-contained, runnable threat demonstrations under examples/:

- lethal-trifecta-walkthrough/ — feeds 5 hook calls (WebFetch, Read .env,
  Bash curl POST + suppression follow-ups) into post-session-guard and
  verifies the Rule-of-Two advisory fires exactly on leg 3. State
  isolated via run-script PID so /tmp/llm-security-session-*.jsonl is
  not polluted. Treffer post-session-guard, ASI01/ASI02, LLM01/LLM02.

- mcp-rug-pull/ — mutates an MCP tool description across 8 stages.
  Each per-update <10% Levenshtein, cumulative reaches 32.2% by stage
  7 — proves the v7.3.0 (E14) mcp-cumulative-drift MEDIUM advisory
  catches slow-burn rug-pulls that the per-update detection would
  miss. Uses LLM_SECURITY_MCP_CACHE_FILE to isolate cache. Treffer
  post-mcp-verify, mcp-description-cache.mjs, OWASP MCP05/LLM03/ASI04.

Each example: README.md + run-*.mjs + expected-findings.md.
Plugin README "Other runnable examples" section + CHANGELOG
[Unreleased] Added bullets + plugin CLAUDE.md "Examples" section
all updated in this commit. Marketplace root README unchanged
since plugin's outward coverage is unchanged ([skip-docs]
covers the marketplace-level gate).
2026-05-05 14:45:15 +02:00
95a511c3ce feat(voyage)!: rename ULTRAEXECUTE_* env vars to TREKEXECUTE_* [skip-docs]
- ULTRAEXECUTE_MAX_TURNS -> TREKEXECUTE_MAX_TURNS
- ULTRAEXECUTE_MAX_BUDGET_USD -> TREKEXECUTE_MAX_BUDGET_USD
- ULTRAEXECUTE_SKIP_PREFLIGHT -> TREKEXECUTE_SKIP_PREFLIGHT

Files: commands/trekexecute.md, templates/headless-launch-template.md,
templates/session-spec-template.md.

Part of voyage-rebrand session 2 (W3.6 / Step 8).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 14:44:52 +02:00
fc69707454 feat(voyage)!: rename git branch namespace ultraplan -> trek [skip-docs]
- commands/trekexecute.md: 6 ultraplan/{slug} refs -> trek/{slug}
- templates/headless-launch-template.md: 7 ultraplan/{slug} refs -> trek/{slug}
- README.md line 273: branch namespace example -> trek/{slug}

Closes the deferred V2 README.md branch-namespace update.

Part of voyage-rebrand session 2 (W3.5 / Step 7).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 14:42:59 +02:00
5f74a670ab feat(voyage)!: rename produced_by field values + validator comments [skip-docs]
- commands/trekexecute.md: produced_by literals -> trekexecute (4 occurrences)
- commands/trekendsession.md: produced_by literals -> trekendsession (2 occurrences)
- tests/validators/next-session-prompt-validator.test.mjs: 11 'ultraexecute-local' refs -> 'trekexecute'
- tests/commands/trekcontinue.test.mjs: 3 fixture strings updated
- tests/lib/cleanup.test.mjs: 1 fixture string updated
- lib/validators/next-session-prompt-validator.mjs: producer-list comment
- docs/HANDOVER-CONTRACTS.md line 432: example producer names updated

Part of voyage-rebrand session 2 (W3.4 / Step 6).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 14:42:21 +02:00
0508edff15 feat(voyage)!: rename type discriminators across validators + fixtures [skip-docs]
- brief-validator: BRIEF_TYPE_VALUES ['ultrabrief','ultrareview'] -> ['trekbrief','trekreview'] + dependent branches
- research-validator: 'ultraresearch-brief' -> 'trekresearch-brief'
- review-validator: 'ultrareview' -> 'trekreview'
- 3 templates frontmatter type:
- 4 synthetic fixtures: ultraplan-synthetic/ultrareview-synthetic -> trek* (frontmatter only; bodies untouched, Jaccard floor preserved)
- 2 trekreview fixtures: type: trekreview
- 6 validator-test fixtures + asserts
- agents/review-coordinator.md frontmatter example

Atomic: validator + fixtures committed together — partial state would cause vacuous
test passes or hard validator rejection.

Part of voyage-rebrand session 2 (W3.3 / Step 5).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 14:40:25 +02:00
f924d329b5 feat(voyage)!: FLAG_SCHEMA keys trek* + arg-parser test cases [skip-docs]
- Rename FLAG_SCHEMA keys ultrabrief|ultraresearch|ultraplan|ultraexecute|ultrareview|ultracontinue -> trek* equivalents
- Update 26 literal key references in tests/lib/arg-parser.test.mjs
- Update parseArgs($ARGUMENTS, 'ultracontinue') -> 'trekcontinue' in commands/trekcontinue.md
- trekendsession.md audited: no parseArgs invocation, no FLAG_SCHEMA entry needed

Atomic per session-spec: schema + tests + consuming commands committed together to
avoid vacuous-pass risk.

Part of voyage-rebrand session 2 (W3.2 / Step 4).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 14:35:01 +02:00
82bd665ba0 chore(ms-ai-architect): KB checkpoint refresh — 30 files (critical 9 + high batch 1) [skip-docs]
- Critical bucket (9 files): substantive content updates basert på MCP-fetch
  - enterprise-governance: DSPM front door, AI-app-kategorier (3), single-tenant Entra ID
  - rag-cost-optimization, observability, ai-services-enterprise, multi-model-strategy: dato-bump
  - deterministic-cost: Copilot Credits offisiell common currency (2025-09-01), CCCU prepurchase
  - gpt5-gpt41-pricing: utvidet Copilot Studio modell-lineup (GPT-5.2, GPT-5.3, Claude 4.6, Grok 4.1)
  - vector-storage, request-batching: dato-bump (DS allerede dekkende)

- High batch 1 (21 files, 10-30): Last updated 2026-04→2026-05 dato-bump
  Substantive Microsoft Learn-endringer var marginale per fetch — kosmetiske oppdateringer.

Resterende: high batch 2 (filer 31-53, 23 filer) i ny sesjon. Se NEXT-SESSION-PROMPT.local.md.
2026-05-05 14:28:35 +02:00
cbc0053957 feat(voyage)!: session-title hook COMMANDS map + voyage prefix [skip-docs]
- Replace 5 ultra*-local keys with trek* equivalents
- Add /trekcontinue + /trekendsession entries
- Change session title prefix ultra: -> voyage:

Part of voyage-rebrand session 2 (W3.1 / Step 3).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 14:28:20 +02:00
47a4ad47d8 feat(voyage)!: rename commands, templates, fixtures for v4.0.0 [skip-docs] 2026-05-05 14:13:44 +02:00
a975c9943c test(ms-ai-architect): add ros-analysis fixture for E2E suite
Synthetic ROS-analyse output for "Acme Kunde-chatbot" (Acme Kommune)
following the same pattern as security-assessment, cost-estimation,
ai-act and summary fixtures. Satisfies all 29 assertions in
tests/test-ros-output.sh:

- 8 phases (Fase 1-8) plus Ledelsessammendrag
- 12 trusler i T-XXX-NN format (MAESTRO + OWASP-mapping)
- 9 risikoer i R-N format
- 10 tiltak i M-N format
- 7 ROS-dimensjoner med X/5-scoring
- 5x5 risikomatrise + restrisiko-tabell
- NS 5814 + ISO 31000 metodikk-referanser
- AI Act, GDPR, OWASP regulatoriske referanser
- MAESTRO + supply-chain referanser (Vedlegg O coverage)

Tar bort den siste pre-eksisterende run-e2e-feilen
(`bash tests/run-e2e.sh` exits 0).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 12:38:49 +02:00
f835777c1e test(llm-security): add e2e suite proving framework works as coordinated system
Three new files in tests/e2e/ (45 tests, 1777 -> 1822):

- attack-chain.test.mjs (17): full hook stack against attack payloads in
  sequence -- prompt injection at the gate; T1/T5/T8 bash evasions;
  pathguard on .env / .ssh; secrets hook on AWS-shaped keys and PEM
  headers; markdown link-title and HTML-comment poisoning in tool
  output; trifecta accumulation over a single session with dedup on
  the next benign call.

- multi-session.test.mjs (9): state persistence across simulated
  session boundaries. Uses the fact that a hook child's process.ppid
  equals the test runner's process.pid, so writing the session state
  file directly simulates "previous session" history. Covers slow-burn
  trifecta (legs spread >50 calls), MCP cumulative description drift
  via LLM_SECURITY_MCP_CACHE_FILE override, and pre-compact transcript
  poisoning in warn / block / clean / missing-file modes.

- scan-pipeline.test.mjs (19): scan-orchestrator + all 10 scanners +
  toxic-flow correlator against poisoned-project (BLOCK / 95 / Extreme)
  and grade-a-project (WARNING / 48 / High). Asserts envelope shape,
  verdict, risk_score, severity counts, OWASP coverage, scanner
  enumeration, and a narrative-coherence cross-check that the BLOCK
  scan strictly outranks the WARNING scan along every axis.

Test files build credential-shaped payloads at runtime via concatenation
so they contain no literal matches for the pre-edit-secrets regexes
(memory rule feedback_secrets_hook_test_fixtures.md).

Doc updates in same commit per marketplace policy:
- CLAUDE.md header: 1777+ -> 1822+ tests, mentions tests/e2e/
- README.md badge tests-1777 -> tests-1822, body text updated
- CHANGELOG.md: new [Unreleased] Added section describing scope

No version bump. No behavior changes outside tests/.
2026-05-05 12:06:57 +02:00
a7a334c8d1 feat(ms-ai-architect): v1.12.0 manuell KB-refresh — fjern launchd/cron-arkitektur
ToS-vurdering konkluderte med at autonom cron-kjøring er unødvendig kompleks
for en solo-fork-and-own-plugin. Apply-fasen krever LLM-resonnering uansett,
så manuell trigger fra en aktiv Claude Code-sesjon er enklere og holder
pluginen klart innenfor Anthropic Consumer Terms paragraf 3 (automated access
only via API key or where explicitly permitted — Claude Code CLI er
eksemptert som offisielt verktøy).

Lagt til:
- commands/kb-update.md — ny /architect:kb-update slash-kommando som driver
  poll, endringsrapport, microsoft_docs_fetch-update og commit fra sesjonen.
  Argumenter: --skip-discover, --priorities, --dry-run, --single-commit
- Catalog-entry i playground HTML for kb-update (categori: tool, 4 input-felt)

Slettet (Wave 3-5 reversert, ~1500 linjer + 7 testmoduler):
- scripts/install-kb-cron.mjs (cross-OS scheduler-installer)
- scripts/kb-update/weekly-kb-cron.mjs (cron-orkestrator med pre-flight, lock,
  backup, claude -p subprocess, post-run verify, rollback)
- scripts/kb-update/templates/ (4 scheduler-templates: launchd plist, systemd
  service+timer, Windows ps1 + README)
- scripts/kb-update/lib/auth-mode.mjs (cron-spesifikk auth validation)
- scripts/kb-update/lib/lock-file.mjs (PID+mtime stale-detection)
- scripts/kb-update/lib/cost-estimat.mjs (pre-flight budget-cap)
- 7 testmoduler under tests/kb-update/ for slettet kode
- tests/test-kb-update.sh (Bash-3.2-shim, erstattet av direkte node --test)

Beholdt (utility-laget fortsatt brukbart):
- run-weekly-update.mjs, report-changes.mjs, build-registry.mjs,
  discover-new-urls.mjs (KB change-detection-pipelinen)
- lib/atomic-write, lib/backup, lib/cross-platform-paths, lib/log-rotate
- 4 testmoduler (42/42 tester PASS)

Endret:
- hooks/scripts/session-start-context.mjs: fjern kb-update-status.json-overvaaking
- tests/run-e2e.sh --kb-update kaller node --test direkte i stedet for shim
- README.md, CLAUDE.md: KB-vedlikehold-seksjon rewriter for manuell modell
- plugin.json: 1.11.0 -> 1.12.0
- Rot README + CLAUDE.md: ms-ai-architect-versjon bumpet

Schedulering er bevisst utenfor scope og overlatt til brukeren — eventuelle
forks som vil ha periodisk varsling kan sette opp egen cron / launchd /
GitHub Actions som kjører rapport-fasen og varsler om aa kjore
/architect:kb-update i CC-sesjon.

Verifisering:
- bash tests/validate-plugin.sh: 219 PASS, 0 FAIL
- bash tests/run-e2e.sh --kb-update: 42/42 inner + suite PASS
- bash tests/run-e2e.sh --playground: 271/271 PASS (statisk + parsers)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 12:03:45 +02:00
97d1101e91 feat(ms-ai-architect): wire kb-update test suite into run-e2e dispatch [skip-docs]
Step 12 — adds --kb-update flag to tests/run-e2e.sh and a Bash 3.2-compatible
shim test-kb-update.sh that runs `node --test tests/kb-update/*.test.mjs`
(shell-glob form; Node 25 rejects directory-form arguments). Shim translates
node --test exit code + parsed pass/fail counts into the e2e-helpers.sh
suite counters (init_suite/print_summary).

Verification:
- Playground baseline 271 PASS unchanged before/after edit
- bash tests/run-e2e.sh --kb-update: exits 0, 110/110 inner tests pass
- bash tests/run-e2e.sh --all: kb-update suite included
- Pre-existing ROS-fixture absence (tests/fixtures/ros-analysis/) is
  unrelated to this change and remains for separate handling

Wave 5 of 7 in v1.12.0 auto-KB-update plan.
Plan: .claude/projects/2026-05-04-kb-update-fork-and-own/plan.md (Step 12)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 11:32:47 +02:00
30d7a2024c feat(ms-ai-architect): add install-kb-cron standalone helper for cross-OS cron registration [skip-docs]
Step 11 of v1.12.0 plan (.claude/projects/2026-05-04-kb-update-fork-and-own/plan.md).

scripts/install-kb-cron.mjs lives at the scripts/ root (not inside
scripts/kb-update/) because it is a plugin-wide install tool, not part of
the KB-update pipeline itself. Reads the appropriate template from
scripts/kb-update/templates/, fills {{NODE_BIN}}, {{PLUGIN_ROOT}},
{{LOG_FILE}}, {{SCHEDULE_HOUR/MINUTE/DAY_OF_WEEK}} placeholders, writes
to the platform-specific scheduler dir, and registers the job:

  macOS  - launchctl bootstrap gui/<uid> <plist>  (load -w fallback)
  Linux  - systemctl --user daemon-reload && enable --now <timer>
  Windows - powershell -ExecutionPolicy Bypass -File <ps1>  (beta)

Flags: --print-only, --target macos|linux|windows, --uninstall, --purge,
--node-bin, --claude-bin, --schedule "M H * * D" (default: Wed 04:23).

UID resolution for launchctl is guarded by process.getuid() POSIX-only
(undefined on Windows). MCP server presence in ~/.claude.json is
warning-only per brief Spørsmål 7. WSL detected via /proc/version.
Cross-OS rendering supported via --print-only --target <other>; install
on a non-host target rejects with explicit error.

11 subprocess + filesystem-snapshot tests in
tests/kb-update/test-install-cron.test.mjs verify --print-only produces
filled templates with no unsubstituted {{...}} placeholders, --print-only
writes nothing under HOME, --uninstall is idempotent on an empty HOME,
--schedule substitutes correctly, and invalid flags reject with non-zero
exit. Tests never invoke launchctl/systemctl/Register-ScheduledTask
against real schedulers.

Tests: 110/110 pass (was 99 before this step).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 11:26:54 +02:00
b0231fdef7 docs(ultraplan-local): D5 close-out — repo cleanup pre-voyage-rebrand [skip-docs]
D5 — final session of post-v3.4.1 stabilisering. Repo prepared for the
upcoming voyage-rebrand (v4.0.0 hard cut: ultraplan-local → voyage,
/ultra*-local → /trek*).

Tracked changes:
- README.md: cut #9 jargon — '### Self-verifying plan chain' →
  '### Manifest-verified steps' with body rewritten to drop the
  'objective completion predicate' jargon.
- package.json: removed 'simulate' script that pointed to
  tests/simulator/run-pipeline.mjs (file never existed; D3 was
  dropped before that work shipped).
- .claude-plugin/marketplace.json: ultraplan-local description
  updated from 'Four-command pipeline' to the current six-command
  shape with Handover 6 + multi-session resumption (matches
  plugin.json).
- docs/_archive-ultra-suite-brief_2.md: deleted (tracked planning-doc
  unrelated to ultraplan-local; 117 lines, no inbound references).

Untracked cleanup (not in commit, gitignored):
- 4 stale plugin-root .local.md (NEXT-SESSION-PROMPT.archived,
  PLAN-v2.1-phase3, V3.0-MULTI-SESSION-PLAN, etc.)
- 3 docs/ planning .local.md (ultracontinue-brief, ultracontinue-design-notes,
  ultraexecute-v2-observations)
- examples/01-add-verbose-flag/perf-baseline.local.md
- .claude/plans/ultraplan-2026-04-17-logger.md
- 9 closed sub-projects under .claude/projects/ (skill-factory,
  ultracontinue, ultrareview-local, ultra-pipeline-speedup,
  examples-02-real-cli, post-v3.4.0-roadmap, spor-c-q3-cache,
  v3.3.1-ultracontinue-fixes)

Cuts #7 (template-duplisering) + #10 (Two kinds of briefs) reviewed
and judged not needed: README has 38 code-fences vs CLAUDE.md 2 (no
overlap), and 'Two kinds of briefs' is already a direct task-vs-
research-brief explanation, not jargon.

D3 + D4 droppet 2026-05-05 — voyage-rebrand renames all ultra*
references; new test infrastructure built against the old names
would need to be renamed in the same pass. Memory pin:
feedback_cleanup_vs_new_code.md.

Tests: 361 / 0 (unchanged — no test changes).
Stabilisering close-out: complete. Repo is ready for voyage-rebrand.
2026-05-05 11:17:00 +02:00
7848d113de feat(ms-ai-architect): session-start hook reads kb-update-status for failure surfacing [skip-docs] 2026-05-05 11:12:37 +02:00
a0528e6ef7 feat(ms-ai-architect): rewrite weekly-kb-cron with portable paths, auth-mode-aware pre-flight, lock+backup+rollback [skip-docs] 2026-05-05 11:10:17 +02:00
03c77b6452 feat(ms-ai-architect): add cross-OS scheduling templates (launchd/systemd/Windows) [skip-docs] 2026-05-05 11:02:44 +02:00
aefe9ef5b4 feat(ms-ai-architect): add lib/log-rotate for bounded log disk use [skip-docs]
Foundation lib for v1.12.0 cron rewrite — closes brief deliverable
"log-rotate" that was missing from the original plan (Phase 9 scope
revision). Standard logrotate idiom, zero dependencies.

- rotateLog(logPath, opts) returns {rotated, dropped, kept}
- Defaults: maxSizeBytes 10 MB, maxGenerations 5 (1 active + 4 rotated)
- No-op when log missing or under threshold
- Over-size: drop oldest, shift .N..1 down by one, move active → .1
- maxGenerations=1 keeps only the active slot (no rotated copies)
- Pure stdlib fs.renameSync chain with silent try/catch on missing gens

8/8 tests pass: missing/under-size/over-size paths, chained 6 rotations
capped at maxGenerations, oldest dropped, two-step content shift.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:54:50 +02:00
2b3f544f86 feat(ms-ai-architect): add lib/auth-mode for cron-safe auth detection [skip-docs]
Foundation lib for v1.12.0 cron rewrite. Detects which Claude auth mode is
in scope and rejects modes that are architecturally incompatible with cron.

Resolution order:
- ANTHROPIC_API_KEY env-var → 'api-key'
- CLAUDE_CODE_OAUTH_TOKEN env-var → 'long-oauth'
- ~/.claude.json onboarded + runner exit 0 → 'subscription-browser-only'
- otherwise → 'unauthenticated'

Subscription browser-OAuth tokens expire ~15h and cannot survive cron — the
detector flags them explicitly so validateAuthForCron throws EAUTHCRON with
a remediation message pointing to `claude setup-token` or ANTHROPIC_API_KEY.

Both runner (subprocess invoker) and claudeJsonPath (~/.claude.json) are
dependency-injected. Tests stub them — no real subprocess spawn, no home-
directory reads.

15/15 tests pass: precedence, env-var detection, onboarded subscription,
non-onboarded fallback, validateAuthForCron throw paths.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:52:53 +02:00
d46f7a3459 feat(ms-ai-architect): add lib/backup with sentinel-guarded rollback [skip-docs]
Foundation lib for v1.12.0 cron rewrite skill-tree backup/restore.
Zero dependencies. Uses fs.cpSync (recursive + preserveTimestamps) without
dereference (Node 22.17.x regression) and without filter (Windows symlink-
type bug).

- backupDir(srcDir, backupRoot, opts) → {backupPath, retentionDays, restore()}
- Backup-id format YYYY-MM-DDTHH-MM-SS (filesystem-safe; no colons)
- .backup-meta.json sentinel written as first action inside backupPath
- restore() writes .rollback-in-progress at backupRoot BEFORE rmSync+cpSync
  so a crashed restore leaves the sentinel for the next run to detect
- detectStaleRollback(backupRoot) — boolean predicate over sentinel
- cleanupOldBackups(backupRoot, retentionDays) — 3-step age resolution:
  meta.created_at → dir mtime → skip-with-warning (never delete a dir
  whose age cannot be established)

12/12 tests pass: timestamp format, content round-trip, sentinel lifecycle,
retention, mtime fallback, unparseable-meta skip, missing-root no-op.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:50:10 +02:00
3e26b94a27 feat(ms-ai-architect): add lib/lock-file with PID+mtime stale detection [skip-docs]
Foundation lib for v1.12.0 cron rewrite. Atomic exclusive create via
fs.writeFileSync('wx'); on EEXIST resolves staleness with OR semantics:
stale if PID is dead OR mtime exceeds threshold. Either alone breaks the
lock — handles SIGKILL orphans (mtime), PID-reuse races (mtime), and
crashed-then-replaced runs (PID).

- acquireLock(lockPath, opts) → {lockPath, release()}
- staleThresholdMs default 1h; refreshIntervalMs opt-in for long runs
- registerCleanup default true (exit/SIGINT/SIGTERM/SIGHUP/uncaughtException)
- isPidAlive uses kill(pid, 0) with EPERM-as-alive nuance

12/12 tests pass: PID liveness, fixture concurrency, idempotent release,
stale variants (dead+old, live+old, fresh+live), staleThresholdMs honored.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:47:05 +02:00
4aac89ca11 docs(ultraplan-local): complete external-architect doc rydding [skip-docs]
D2 of post-v3.4.1 stabilisering. Removes 14 plugin-name references from
agents/, commands/, and docs/ tracked files (CLAUDE.md/README.md/SECURITY.md
were ryddet in v3.4.1 commit 6bca3fb).

The external architect plugin was moved out of the public marketplace
2026-05-04 due to ToS concerns around future skill sources. References in
prose are now stale or misleading for public users. The architecture/overview.md
filesystem slot remains available for any compatible producer — discovery
is plugin-agnostic via lib/validators/architecture-discovery.mjs (drift-WARN,
never drift-FAIL).

Files:
- agents/planning-orchestrator.md (1 ref generalized)
- commands/ultraplan-local.md (2 refs generalized; missed by prompt inventory)
- docs/HANDOVER-CONTRACTS.md (4 refs generalized; Handover 3 + stability summary)
- docs/architect-bridge-test.md (deleted; was a public-only bridge checklist)
- docs/subagent-delegation-audit.md (5 refs/rows removed; intervention #5 dropped, recommendation adjusted)

CHANGELOG.md retains historical references (20 occurrences) intentionally.

Verification:
- grep tracked non-CHANGELOG md: 0 references remaining
- npm test: 361/361 pass (baseline preserved)
2026-05-05 10:46:29 +02:00
f339437e6d docs(ultraplan-local): seal Path C closed with Q3 NEGATIVE finding [skip-docs]
D1 of post-v3.4.1 stabilisering. Path C (cache-warm sentinel + identical-tool
parallel) is closed 2026-05-05 per Q3 experiment NEGATIVE result:
median cache_creation_input_tokens = 163,903 across 3 fork-children at
186K parent context (CC v2.1.128, Sonnet 4.6).

Master-plan thresholds: <= 1,500 POSITIVE / >= 3,500 NEGATIVE — NEGATIVE
solidly. CLAUDE_CODE_FORK_SUBAGENT does not preserve cache prefix across
identical-tool children at our context size.

Path C migration is deferred indefinitely. Reassessment is appropriate
when CC v2.2.xxx ships fork-cache-relevant features. Harness
(scripts/q3-cache-prefix-experiment.mjs) and analyser
(lib/stats/cache-analyzer.mjs) remain available for re-run.

Brief: .claude/projects/2026-05-04-spor-c-q3-cache-prefix-experiment/brief.md
Result: q3-experiment-results.local.md (gitignored)
2026-05-05 10:36:36 +02:00
f2b76b6d8e feat(ms-ai-architect): add lib/cost-estimat heuristic for API-key budget [skip-docs]
Pure auth-mode-aware cost estimator for v1.12.0 cron pre-flight.

Heuristic: critical+high files only (medium/low excluded per brief);
3000 input + 1500 output tokens per file at Sonnet pricing
($3/M in, $15/M out).

Auth-mode behavior:
- api-key:   numeric usd, kvote_warn off  (subject to dollar-cap)
- long-oauth, subscription-browser-only:
             usd null, kvote_warn on      (quota, no dollar billing)
- unauthenticated/missing: best-effort api-key estimate

11/11 tests pass; covers both billing modes plus token-math
invariance across auth-mode (auth only affects dollar-field, not tokens).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:34:37 +02:00
4a615b10ce feat(ms-ai-architect): add lib/atomic-write for crash-safe state files [skip-docs]
Foundation lib for status-fil + lock-fil writes in v1.12.0 cron rewrite.
Pattern: writeFileSync to <path>.tmp.<pid>.<random> then renameSync to
target. Defends against half-written files; readers either see the
previous version or the new one, never a partial.

- atomicWriteSync(path, content) — string or Buffer
- atomicWriteJson(path, obj) — 2-space indent, trailing newline
- Windows EEXIST/EPERM defensive fallback (unlink target + rename)
- Best-effort tmp cleanup on writeFileSync failure
- crypto.randomInt(0, 2**32) two-arg form (unambiguous across Node)

9/9 tests pass including 50-way concurrent-write fuzzer (async-aware
withTmp helper).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:32:13 +02:00
57fcdf7158 feat(ms-ai-architect): add lib/cross-platform-paths for cache/log/state/backup dirs [skip-docs]
First foundation lib for v1.12.0 auto-KB-update. Resolves per-OS paths:
- macOS: ~/Library/{Caches,Logs,Application Support}/<app>/
- Linux: XDG_CACHE_HOME / XDG_STATE_HOME with ~/.cache, ~/.local/state fallbacks
- Windows: %LOCALAPPDATA%\<app>\{Cache,Logs,State}

Plus getBackupDir(pluginRoot) → <pluginRoot>/.kb-backup (gitignored).

All four functions auto-mkdir target. Dependency-injection via opts
({platform, homedir, env}) makes the lib pure-testable; 13/13 tests
pass under tmpdir isolation without touching real ~/ paths.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-05 10:30:31 +02:00