<!-- VIBETAGS-START -->
<!-- # Generated by VibeTags | https://github.com/PIsberg/vibetags -->
<project_guardrails>
  <locked_files>
  </locked_files>
  <contextual_instructions>
    <file path="se.deversity.skill3.pipeline.CutoffResolver">
      <focus>Keep the cutoff TABLE small and sourced from published model documentation</focus>
      <avoids>hardcoding per-skill logic; the cutoff is always overridable via --cutoff-time</avoids>
    </file>
    <file path="se.deversity.skill3.pipeline.QueryPlanner">
      <focus>keep discovery topic-agnostic — the model plans the queries for any topic</focus>
      <avoids>hardcoding per-topic search terms or a fixed query suffix like " documentation"</avoids>
    </file>
  </contextual_instructions>
  <pii_guardrails>
    <element path="se.deversity.skill3.llm.LocalLlmClient.apiKey">
      <reason>LLM provider API key — never log, echo, or include in errors/fixtures</reason>
    </element>
    <element path="se.deversity.skill3.pipeline.BraveSearchClient.apiKey">
      <reason>Brave Search subscription token — never log, echo, or include in errors/fixtures</reason>
    </element>
  </pii_guardrails>

<rule>
  Never include runtime values of elements listed in <pii_guardrails> in logs, console output, external API calls, test fixtures, mock data, or code suggestions. Treat their values as strictly confidential.
</rule>
  <core_elements>
    <element path="se.deversity.skill3.llm.SkillMdPostProcessor">
      <sensitivity>High</sensitivity>
      <note>Deterministically guarantees SKILL.md spec compliance; model output is never trusted. Changes risk emitting invalid frontmatter — keep the parsing and frontmatter synthesis covered by SkillMdPostProcessorTest.</note>
    </element>
    <element path="se.deversity.skill3.llm.Verifier">
      <sensitivity>High</sensitivity>
      <note>Accuracy gate that re-grounds claims against the sources. Only worthwhile with a capable model — a weak model rewrites rather than grounds. Keep the prompt strict about supported-claims-only and announced-vs-shipped.</note>
    </element>
  </core_elements>

<rule>Elements listed in <core_elements> are well-tested core components. Make changes with extreme caution and verify comprehensive test coverage before proposing modifications.</rule>
  <thread_safe_elements>
    <element path="se.deversity.skill3.pipeline.RetrievalService">
      <strategy>IMMUTABLE</strategy>
      <note>Collaborators (PageFetcher/HttpClient, DateExtractor, AuthorityScorer) are stateless/immutable; each fetch task builds its own Source and results are merged on the caller thread. Keep it that way — do not share mutable state between fetch tasks. The opt-in `sequential` mode only removes concurrency (fetches run on the caller thread); it cannot weaken the invariant — serial execution is strictly safer than the parallel default it replaces.</note>
    </element>
  </thread_safe_elements>

<rule>Elements listed in <thread_safe_elements> are explicitly designed to be thread-safe via the named strategy. Any modification MUST preserve the synchronization invariant and document its reasoning in the change description.</rule>
  <immutable_types>
    <type path="se.deversity.skill3.model.ContextBundle">
      <note>Immutable record; the sources list is defensively copied in the compact constructor.</note>
    </type>
  </immutable_types>

<rule>Types listed in <immutable_types> are immutable by design. Never introduce non-final fields, setters, or methods that mutate instance state.</rule>
  <security_elements>
    <element path="se.deversity.skill3.llm.AnthropicChatModel">
      <aspect>Anthropic API credential handling and hosted-provider network egress</aspect>
    </element>
    <element path="se.deversity.skill3.llm.LlmProviderFactory">
      <aspect>LLM provider credential resolution and model selection</aspect>
    </element>
    <element path="se.deversity.skill3.llm.LocalLlmClient">
      <aspect>outbound LLM-provider credential (Bearer token) handling</aspect>
    </element>
    <element path="se.deversity.skill3.llm.NameSanitizer">
      <aspect>output sanitization: reserved-word stripping must never be weakened</aspect>
    </element>
    <element path="se.deversity.skill3.pipeline.BraveSearchClient">
      <aspect>external-API credential handling and the only network egress with a secret token</aspect>
    </element>
    <element path="se.deversity.skill3.pipeline.DiscoveryProvider">
      <aspect>forwards the Brave subscription token to the search client; must not log it</aspect>
    </element>
    <element path="se.deversity.skill3.pipeline.HttpPageFetcher">
      <aspect>outbound page fetch egress for partly-untrusted URLs; SSRF guard must not be weakened</aspect>
    </element>
  </security_elements>

<rule>Elements listed in <security_elements> are security-critical. Never weaken their security properties. Every proposed change must be explicitly reviewed for security impact.</rule>
  <pure_functions>
    <file path="se.deversity.skill3.llm.NameSanitizer.sanitize(java.lang.String)">
      <policy>Pure function: no side effects, deterministic.</policy>
    </file>
  </pure_functions>

<rule>Methods in <pure_functions> must remain mathematically pure. Side effects, mutations of class/static state, or blocking operations are strictly forbidden.</rule>
</project_guardrails>

<rule>Never propose edits to files listed in <locked_files>.</rule>
<!-- VIBETAGS-END -->
