fix(ms-ai-architect): RX-P2 reg-kjede-wiring + komprehensiv agent-sti-forankring [skip-docs]

- classify->dpia->ros kjede-wiring: dpia/ros Task-templater far eksplisitte
  AI Act-klassifiserings- + DPIA-funn-felt (kjede-data agentene allerede branchet pa)
- dpia-agent uutforbar "spor bruker" -> "marker vurderingen" (Hvis-ikke-klassifisert
  + Error Handling); speilet til ros-analysis-agent
- adr-writer-agent: Write-verktoy fjernet, returnerer ADR-markdown til hovedkontekst
  (command er eneste skriver -- subagenter skriver aldri)
- KB-sti-forankring (komprehensiv): 36 bare referanse-subdir-stier i 6 agenter +
  2 commands fullkvalifisert med CLAUDE_PLUGIN_ROOT/skills/<skill>/references/ ---
  ogsa innen-skill kortformer, uresolverbare i installert modus
- mekanisme: validate-plugin.sh Check 6d (bare-subdir-lint m/ hyphen-guard) +
  negativ-probe-test (beviser tenner) + RX-P2 wiring-regresjonstester

Suite 859/859 exit 0. validate-plugin 250 PASS / 0 FAIL. 145 forankrede stier
verifisert eksisterende (0 mangler).
This commit is contained in:
Kjell Tore Guttormsen 2026-07-15 12:17:01 +02:00
commit b68514487c
13 changed files with 151 additions and 36 deletions

View file

@ -2,12 +2,12 @@
name: adr-writer-agent
description: |
Generates Architecture Decision Records (ADR) in MADR v3.0 format from structured input.
Reads adr-template.md, fills in from session context, and writes to file.
Reads adr-template.md, fills in from session context, and returns the ADR markdown to the main context.
Use when architect:adr needs to generate a complete ADR document.
Triggers on: ADR generation, decision documentation, architect:adr delegation.
model: opus
color: orange
tools: ["Read", "Write", "Glob"]
tools: ["Read", "Glob"]
---
# ADR Writer Agent
@ -87,9 +87,9 @@ Fill in every section of the MADR template:
**Validering og oppfølging**: Concrete next steps with responsible party.
### 4. Write to File
### 4. Return to Main Context
Write the ADR to the location specified in the input. Default: `docs/adr/ADR-NNN-[slug].md`
Return the complete ADR markdown as your final message. The main context (the `/architect:adr` command) writes it to file — do not write files yourself (you run as a subagent).
## Output Format
@ -101,7 +101,7 @@ The generated ADR should be:
## Quality Checklist
Before writing:
Before returning:
- [ ] All template sections filled (no placeholders)
- [ ] Compliance section included (even if "Not assessed")
- [ ] Confidence level reflects actual analysis quality

View file

@ -164,13 +164,13 @@ Read relevant knowledge base files:
- `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-advisor/references/architecture/licensing-matrix.md` — License requirements
Load domain-specific references only when dimension requires depth (max 2-3 additional):
- AI Act: `responsible-ai/ai-act-compliance-guide.md`, `responsible-ai/ai-act-annex-iii-checklist.md`
- Governance: `responsible-ai/ai-governance-structure-framework.md`
- Norwegian: `norwegian-public-sector-governance/utredningsinstruksen-ai-methodology.md`
- Security: `ai-security-engineering/ai-threat-modeling-stride.md`
- Cost: `cost-optimization/azure-ai-foundry-cost-governance.md`, `cost-optimization/deterministic-cost-calculation-model.md`
- RAG-arkitektur (når løsningen er RAG-/gjenfinningsbasert): `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/rag-architecture/rag-core-patterns.md`, `rag-architecture/agentic-rag-patterns.md`, `rag-architecture/rag-evaluation-frameworks.md`
- MLOps/GenAIOps (når løsningen har produksjons-/livssyklusfokus): `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/mlops-genaiops/genaiops-llm-specific-practices.md`, `mlops-genaiops/monitoring-observability-ml-systems.md`, `mlops-genaiops/model-deployment-strategies-azure.md`
- AI Act: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/ai-act-compliance-guide.md`, `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/ai-act-annex-iii-checklist.md`
- Governance: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/ai-governance-structure-framework.md`
- Norwegian: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/norwegian-public-sector-governance/utredningsinstruksen-ai-methodology.md`
- Security: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-security/references/ai-security-engineering/ai-threat-modeling-stride.md`
- Cost: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-security/references/cost-optimization/azure-ai-foundry-cost-governance.md`, `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-security/references/cost-optimization/deterministic-cost-calculation-model.md`
- RAG-arkitektur (når løsningen er RAG-/gjenfinningsbasert): `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/rag-architecture/rag-core-patterns.md`, `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/rag-architecture/agentic-rag-patterns.md`, `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/rag-architecture/rag-evaluation-frameworks.md`
- MLOps/GenAIOps (når løsningen har produksjons-/livssyklusfokus): `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/mlops-genaiops/genaiops-llm-specific-practices.md`, `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/mlops-genaiops/monitoring-observability-ml-systems.md`, `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/mlops-genaiops/model-deployment-strategies-azure.md`
## Virksomhetskontekst (automatisk)

View file

@ -60,9 +60,9 @@ Read these core files:
- `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-advisor/references/architecture/cost-models.md` — Cost model templates
Load additional files only when estimate requires specific depth:
- PTU: `cost-optimization/ptu-vs-paygo-economics.md`
- Caching: `cost-optimization/semantic-caching-patterns.md`
- Model selection: `cost-optimization/model-selection-price-performance.md`
- PTU: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-security/references/cost-optimization/ptu-vs-paygo-economics.md`
- Caching: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-security/references/cost-optimization/semantic-caching-patterns.md`
- Model selection: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-security/references/cost-optimization/model-selection-price-performance.md`
## Virksomhetskontekst (automatisk)

View file

@ -22,10 +22,10 @@ Read these core files:
- `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/ai-impact-assessment-framework.md` — Konsekvensvurdering
Load additional files only when assessment requires specific depth:
- Bias: `responsible-ai/bias-detection-mitigation-strategies.md`
- PII: `ai-security-engineering/pii-detection-norwegian-context.md`
- Data leakage: `ai-security-engineering/data-leakage-prevention-ai.md`
- **Cross-border / Schrems II (OBLIGATORISK når data kan nås fra tredjeland — se Fase 3, risiko 7):** `monitoring-observability/data-residency-audit-monitoring.md` — EDPB seks-stegs-TIA, CLOUD Act/FISA 702/EO 12333-restanalyse, EO 14086/DPF-status, tekniske tilleggstiltak
- Bias: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/bias-detection-mitigation-strategies.md`
- PII: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-security/references/ai-security-engineering/pii-detection-norwegian-context.md`
- Data leakage: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-security/references/ai-security-engineering/data-leakage-prevention-ai.md`
- **Cross-border / Schrems II (OBLIGATORISK når data kan nås fra tredjeland — se Fase 3, risiko 7):** `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/monitoring-observability/data-residency-audit-monitoring.md` — EDPB seks-stegs-TIA, CLOUD Act/FISA 702/EO 12333-restanalyse, EO 14086/DPF-status, tekniske tilleggstiltak
## Virksomhetskontekst (automatisk)
@ -47,7 +47,7 @@ Før DPIA-vurderingen, sjekk om AI Act-klassifisering er utført:
- Integrer deployer-forpliktelser fra `ai-act-deployer-obligations.md` som tiltak i Fase 4
### Hvis ikke klassifisert
- Spør om det bør gjøres: "Er det gjennomført AI Act-klassifisering for dette systemet? Hvis nei, anbefaler vi `/architect:classify` — men DPIA fortsetter uansett."
- Marker i rapporten at AI Act-klassifisering ikke er dokumentert, og anbefal `/architect:classify` som neste steg (du kjører som subagent uten brukertur — still ingen spørsmål)
- Fortsett DPIA som normalt — klassifisering er ikke forutsetning
### Ekstra KB-referanser for AI Act
@ -93,7 +93,7 @@ Risk categories for AI systems:
#### Cross-border / Schrems II — obligatorisk TIA (risiko 7)
Når systemet bruker en amerikansk-eid skyleverandør (Azure/Microsoft 365/Foundry) eller data på annen måte kan nås fra tredjeland, **er det ikke nok å navngi risikoen** — load `monitoring-observability/data-residency-audit-monitoring.md` og gjennomfør EDPB seks-stegs Transfer Impact Assessment:
Når systemet bruker en amerikansk-eid skyleverandør (Azure/Microsoft 365/Foundry) eller data på annen måte kan nås fra tredjeland, **er det ikke nok å navngi risikoen** — load `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/monitoring-observability/data-residency-audit-monitoring.md` og gjennomfør EDPB seks-stegs Transfer Impact Assessment:
1. Kartlegg overføringene (inkl. residual: support, troubleshooting, telemetri)
2. Identifiser overføringsverktøyet (adekvansvedtak / SCCs / unntak)
@ -141,9 +141,9 @@ Read the AI system description or architecture proposal. Extract:
### 2. Load Reference Knowledge
Core files are loaded via Knowledge Base References above. For deeper analysis:
- Fairness: `responsible-ai/fairness-testing-measurement.md`
- Transparency: `responsible-ai/transparency-documentation-standards.md`
- Human oversight: `responsible-ai/human-in-the-loop-oversight.md`
- Fairness: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/fairness-testing-measurement.md`
- Transparency: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/transparency-documentation-standards.md`
- Human oversight: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/human-in-the-loop-oversight.md`
### 3. Validate Latest Guidance
Use `microsoft_docs_search` for:
@ -225,7 +225,7 @@ Follow the output format below with all sections completed.
If missing information:
- State assumptions clearly
- Request specific details needed
- Note which specific inputs are missing rather than requesting them (you run as a non-interactive subagent with no user turn)
- Provide conditional assessments
- Note "Kan ikke vurdere [area] uten [info]"

View file

@ -34,8 +34,8 @@ Et kompakt sammendrag av virksomhetskonteksten injiseres ambient i hovedøkten v
## Lokal KB-baseline (betinget — RAG / MLOps / engineering-temaer)
Når forskningstemaet er RAG, gjenfinning, MLOps eller GenAIOps, les den relevante engineering-kjernefilen **først** som hypotese-baseline — verifiser den deretter mot live Microsoft Learn. KB-en kan være utdatert; **MCP-resultatet er fasit**.
- RAG/gjenfinning: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/rag-architecture/rag-core-patterns.md`, `rag-architecture/agentic-rag-patterns.md`
- MLOps/GenAIOps: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/mlops-genaiops/genaiops-llm-specific-practices.md`, `mlops-genaiops/llm-evaluation-production.md`
- RAG/gjenfinning: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/rag-architecture/rag-core-patterns.md`, `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/rag-architecture/agentic-rag-patterns.md`
- MLOps/GenAIOps: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/mlops-genaiops/genaiops-llm-specific-practices.md`, `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/mlops-genaiops/llm-evaluation-production.md`
Les maks 2 baseline-filer. **Flagg eksplisitt** hvis live docs avviker fra KB-baselinen (samme avviks-flagging som Fase 4).

View file

@ -36,12 +36,12 @@ Alle stier under `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/norwe
| Sektor oppdaget (helse/transport/finans/justis/utdanning) | `ros-sector-checklists.md` |
| Multi-agent / agent-orkestrering | `ros-maestro-multiagent.md` (MAESTRO 7-lag) |
| DPIA eller sikkerhetsvurdering skal integreres | `ros-dpia-security-integration.md` |
| AI Act-dybde i dimensjon 6 | `responsible-ai/ai-act-classification-methodology.md` + `responsible-ai/ai-act-provider-obligations.md` (maks 2) |
| AI Act-dybde i dimensjon 6 | `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/ai-act-classification-methodology.md` + `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/ai-act-provider-obligations.md` (maks 2) |
### Referanse (last kun ved eksplisitt behov, ikke default)
- `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-security/references/ai-security-engineering/security-scoring-rubrics-6x5.md` — scoringsmønster-referanse
- `ros-analyse-ai-systems.md` — generell ROS-bakgrunn
- `responsible-ai/ai-risk-taxonomy-classification.md` — risikotaksonomi
- `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/ai-risk-taxonomy-classification.md` — risikotaksonomi
**Budsjett:** kjerne (4) + betinget (maks 2-3 på trigger) = typisk 5-7 filer. Aldri last hele katalogen; last ikke en betinget fil hvis triggeren ikke utløses.
@ -273,7 +273,7 @@ Risk Levels: Low (1-6), Medium (7-12), High (13-19), Critical (20-25)
If missing information:
- State assumptions clearly
- Request specific details needed
- Note which specific inputs are missing rather than requesting them (you run as a non-interactive subagent with no user turn)
- Provide conditional assessments
- Note "Kan ikke vurdere [area] uten [info]"

View file

@ -26,9 +26,9 @@ Read these core files:
- `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-security/references/ai-security-engineering/ai-threat-modeling-stride.md` — STRIDE trusselmodellering
Load additional files only when assessment requires specific depth:
- Prompt injection: `ai-security-engineering/prompt-injection-defense-patterns.md`
- Governance: `responsible-ai/ai-act-compliance-guide.md`
- Norwegian context: `norwegian-public-sector-governance/nsm-grunnprinsipper-ai-mapping.md`
- Prompt injection: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-security/references/ai-security-engineering/prompt-injection-defense-patterns.md`
- Governance: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/ai-act-compliance-guide.md`
- Norwegian context: `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/norwegian-public-sector-governance/nsm-grunnprinsipper-ai-mapping.md`
## Virksomhetskontekst (automatisk)

View file

@ -41,6 +41,7 @@ Gjennomfør en komplett DPIA for følgende AI-system:
**Registrerte:** [hvem som berøres]
**Behandlingsgrunnlag:** [GDPR art. 6/9]
**Kontekst:** [sektor/kontekst — offentlig, privat, finans, helse, etc.]
**AI Act-klassifisering (fra /architect:classify, hvis utført):** [risikonivå + rolle + Annex III-kategori — ellers "ikke klassifisert"]
Les kunnskapsbasene (kjerne):
- ${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/norwegian-public-sector-governance/dpia-norwegian-methodology-ai.md

View file

@ -34,8 +34,8 @@ Les `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-advisor/references/architecture/poc-temp
### 3b. Les domene-spesifikke mønstre (betinget)
Hvis use-caset treffer et engineering-domene, les 1-2 kjernefiler for å forankre scope og suksesskriterier (ikke hele katalogen):
- **RAG / gjenfinning:** `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/rag-architecture/rag-core-patterns.md`, `rag-architecture/rag-evaluation-frameworks.md` — sett målbare gjenfinnings-/grounding-kriterier
- **MLOps / produksjonssetting:** `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/mlops-genaiops/genaiops-llm-specific-practices.md`, `mlops-genaiops/llm-evaluation-production.md` — POC-evaluering + driftskriterier
- **RAG / gjenfinning:** `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/rag-architecture/rag-core-patterns.md`, `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/rag-architecture/rag-evaluation-frameworks.md` — sett målbare gjenfinnings-/grounding-kriterier
- **MLOps / produksjonssetting:** `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/mlops-genaiops/genaiops-llm-specific-practices.md`, `${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-engineering/references/mlops-genaiops/llm-evaluation-production.md` — POC-evaluering + driftskriterier
### 4. Generer POC-plan

View file

@ -43,6 +43,8 @@ Gjennomfør en [komplett / quick] ROS-analyse for følgende AI-system:
**Sektor:** [sektor]
**Borgermøtende:** [ja/nei]
**Kontekst:** [ytterligere kontekst]
**AI Act-klassifisering (dimensjon 6, fra /architect:classify):** [risikonivå + rolle — ellers "ikke klassifisert"]
**DPIA-funn (fra /architect:dpia, hvis utført):** [sentrale personvernrisikoer — ellers "ikke utført"]
[**Modus:** Quick (top-10 risikoer, trafikklys) — if --quick]
Les kunnskapsbasene per last-kontrakten i agentfilen — kjerne (alltid) + betinget (kun på trigger):
@ -57,7 +59,7 @@ Betinget (kun når triggeren utløses):
- ros-sector-checklists.md (hvis relevant sektor oppdaget)
- ros-maestro-multiagent.md (hvis multi-agent / agent-orkestrering)
- ros-dpia-security-integration.md (hvis DPIA/sikkerhet skal integreres)
- responsible-ai/ai-act-classification-methodology.md + ai-act-provider-obligations.md (hvis AI Act-dybde i dimensjon 6)
- ${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/ai-act-classification-methodology.md + ${CLAUDE_PLUGIN_ROOT}/skills/ms-ai-governance/references/responsible-ai/ai-act-provider-obligations.md (hvis AI Act-dybde i dimensjon 6)
Lever en [komplett ROS-rapport med alle 8 faser / Quick ROS med top-10 og trafikklys]."
```

View file

@ -0,0 +1,45 @@
// RX-P2 regression guards: classify→dpia→ros chain wiring (del 1), removal of the
// unexecutable "ask user" subagent instructions (del 2), and single ADR write-ownership
// (del 4). Path anchoring (del 3) + its lint (del 5) are enforced by validate-plugin.sh
// Check 6d via test-validate-plugin.test.mjs.
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
const here = dirname(fileURLToPath(import.meta.url));
const root = join(here, '..', '..'); // tests/kb-update -> plugin root
const read = (rel) => readFileSync(join(root, rel), 'utf8');
// --- Del 1: chain wiring — the Task templates must carry explicit chain-data fields ---
test('dpia.md Task template passes AI Act classification as chain-data', () => {
const dpia = read('commands/dpia.md');
assert.match(dpia, /\*\*AI Act-klassifisering \(fra \/architect:classify/);
});
test('ros.md Task template passes AI Act classification (dim. 6) + DPIA findings as chain-data', () => {
const ros = read('commands/ros.md');
assert.match(ros, /\*\*AI Act-klassifisering \(dimensjon 6/);
assert.match(ros, /\*\*DPIA-funn \(fra \/architect:dpia/);
});
// --- Del 2: no unexecutable "ask the user" instructions in Task-spawned subagents ---
test('dpia-agent.md no longer instructs the subagent to ask the user', () => {
const agent = read('agents/dpia-agent.md');
assert.doesNotMatch(agent, /Spør om det bør gjøres/);
assert.doesNotMatch(agent, /Request specific details needed/);
});
test('ros-analysis-agent.md no longer instructs the subagent to ask the user', () => {
const agent = read('agents/ros-analysis-agent.md');
assert.doesNotMatch(agent, /Request specific details needed/);
});
// --- Del 4: adr-writer-agent returns content; the command is the single writer ---
test('adr-writer-agent.md does not carry the Write tool and does not write files', () => {
const agent = read('agents/adr-writer-agent.md');
const toolsLine = agent.split('\n').find((l) => l.startsWith('tools:')) || '';
assert.doesNotMatch(toolsLine, /Write/, 'adr-writer-agent must not have the Write tool (subagents never write)');
assert.doesNotMatch(agent, /### 4\. Write to File/);
});

View file

@ -6,6 +6,7 @@ import assert from 'node:assert/strict';
import { execFileSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { writeFileSync, rmSync } from 'node:fs';
const here = dirname(fileURLToPath(import.meta.url));
const pluginRoot = join(here, '..', '..'); // tests/kb-update -> plugin root
@ -23,3 +24,42 @@ test('validate-plugin.sh passes (frontmatter, encoding, KB refs, plugin.json, in
assert.match(out, /VALIDATION PASSED/);
assert.doesNotMatch(out, /VALIDATION FAILED/);
});
// RX-P2: prove Check 6d has teeth — an unanchored reference-subdir path must be caught.
// Without a negative probe, the positive test above only proves the plugin is currently
// clean, not that 6d actually fires.
test('validate-plugin.sh Check 6d catches an unanchored reference-subdir path (negative probe)', () => {
const probe = join(pluginRoot, 'agents', '__rx_p2_6d_probe__.md');
writeFileSync(
probe,
[
'---',
'name: rx-p2-6d-probe',
'description: temporary probe for the 6d negative test',
'model: opus',
'color: blue',
'tools: ["Read"]',
'---',
'',
'# Probe',
'',
'Load: `responsible-ai/ai-act-compliance-guide.md`',
'',
].join('\n'),
);
try {
let failed = false;
let out = '';
try {
out = execFileSync('bash', [script], { encoding: 'utf8', cwd: pluginRoot });
} catch (err) {
failed = true;
out = `${err.stdout || ''}${err.stderr || ''}`;
}
assert.ok(failed, 'validate-plugin.sh must exit non-zero when a bare reference-subdir path is present');
assert.match(out, /bare reference-subdir path/);
assert.match(out, /__rx_p2_6d_probe__\.md/);
} finally {
rmSync(probe, { force: true });
}
});

View file

@ -349,6 +349,33 @@ else
pass "No sonnet/haiku pinned in Task delegations"
fi
# 6d: every bundled reference-subdir path must be ${CLAUDE_PLUGIN_ROOT}-anchored.
# Short-forms like `responsible-ai/foo.md` (a reference subdir + file, without the
# full skills/<skill>/references/ prefix) resolve only in dev cwd -- installed mode
# breaks. A path is anchored iff the subdir is immediately preceded by '/'
# (.../references/<subdir>/). The (^|[^A-Za-z0-9._/-]) guard fires on bare short-forms
# (preceded by backtick/space/comma/colon) while skipping anchored paths (preceded
# by '/') and compound subdir names (e.g. 'architecture' inside 'rag-architecture',
# preceded by '-').
REF_SUBDIRS='architecture|copilot-extensibility|development|platforms|prompt-engineering|agent-orchestration|api-management|azure-ai-services|data-engineering|mlops-genaiops|multi-modal|rag-architecture|monitoring-observability|norwegian-public-sector-governance|responsible-ai|bcdr|hybrid-edge|ai-security-engineering|cost-optimization|performance-scalability'
subdir_offenders=0
for f in "$PLUGIN_ROOT"/commands/*.md "$PLUGIN_ROOT"/agents/*.md; do
[ -f "$f" ] || continue
rel="${f#$PLUGIN_ROOT/}"
bare="$(grep -nE "(^|[^A-Za-z0-9._/-])($REF_SUBDIRS)/[A-Za-z0-9._-]+\.md" "$f" || true)"
if [ -n "$bare" ]; then
while IFS= read -r bline; do
[ -n "$bline" ] || continue
lineno="${bline%%:*}"
fail "$rel:$lineno: bare reference-subdir path (needs \${CLAUDE_PLUGIN_ROOT}/skills/<skill>/references/ prefix for installed mode)"
subdir_offenders=$((subdir_offenders + 1))
done <<< "$bare"
fi
done
if [ "$subdir_offenders" -eq 0 ]; then
pass "All reference-subdir paths are \${CLAUDE_PLUGIN_ROOT}-anchored"
fi
echo ""
# -------------------------------------------------------