feat: referentiel projets dynamique + validation nommage by design

Durcit la convention de nommage des projets (dérive constatée : 'Sliding
Automation', 'code_versioning'... au lieu des formes canoniques).

- trilium_api.py : projets_canoniques() lit le référentiel = valeurs du label
  projet sur les notes de type=projet (source unique, pas de constante en dur).
  Note-projet CodeVersioning créée (manquait).
- mcp_server.py : _valider_projet() branché dans les 6 tools de création
  (add_decision/history/backlog, new_conversation, create_entite, add_skill).
  Refuse un projet non canonique (suggestion si faute) ou inconnu (renvoi au
  processus de création de projet). Ne verrouille pas si référentiel illisible.
- lint_audit.py : VAL-nommage aligné sur le référentiel (attrape casse, espace
  ET snake_case ; l'ancien 'contient un espace' ratait code_versioning).
- Données : 79 notes ré-étiquetées vers les 3 formes canoniques.

Quality by design : l'erreur de nommage devient impossible à l'écriture, le
Lint n'est plus que le filet de sécurité.
This commit is contained in:
2026-07-17 14:59:33 +02:00
parent d1e67431b6
commit 943acbc573
2425 changed files with 710525 additions and 6 deletions
@@ -0,0 +1,171 @@
from __future__ import annotations
import sys as _sys
from typing import Any as _Any
from typing_extensions import Sentinel
from ._pydantic_core import (
ArgsKwargs,
MultiHostUrl,
PydanticCustomError,
PydanticKnownError,
PydanticOmit,
PydanticSerializationError,
PydanticSerializationUnexpectedValue,
PydanticUndefined,
PydanticUndefinedType,
PydanticUseDefault,
SchemaError,
SchemaSerializer,
SchemaValidator,
Some,
TzInfo,
Url,
ValidationError,
__version__,
from_json,
to_json,
to_jsonable_python,
)
from .core_schema import CoreConfig, CoreSchema, CoreSchemaType, ErrorType
if _sys.version_info < (3, 11):
from typing_extensions import NotRequired as _NotRequired
else:
from typing import NotRequired as _NotRequired
if _sys.version_info < (3, 12):
from typing_extensions import TypedDict as _TypedDict
else:
from typing import TypedDict as _TypedDict
__all__ = [
'__version__',
'UNSET',
'CoreConfig',
'CoreSchema',
'CoreSchemaType',
'SchemaValidator',
'SchemaSerializer',
'Some',
'Url',
'MultiHostUrl',
'ArgsKwargs',
'PydanticUndefined',
'PydanticUndefinedType',
'SchemaError',
'ErrorDetails',
'InitErrorDetails',
'ValidationError',
'PydanticCustomError',
'PydanticKnownError',
'PydanticOmit',
'PydanticUseDefault',
'PydanticSerializationError',
'PydanticSerializationUnexpectedValue',
'TzInfo',
'to_json',
'from_json',
'to_jsonable_python',
]
class ErrorDetails(_TypedDict):
type: str
"""
The type of error that occurred, this is an identifier designed for
programmatic use that will change rarely or never.
`type` is unique for each error message, and can hence be used as an identifier to build custom error messages.
"""
loc: tuple[int | str, ...]
"""Tuple of strings and ints identifying where in the schema the error occurred."""
msg: str
"""A human readable error message."""
input: _Any
"""The input data at this `loc` that caused the error."""
ctx: _NotRequired[dict[str, _Any]]
"""
Values which are required to render the error message, and could hence be useful in rendering custom error messages.
Also useful for passing custom error data forward.
"""
url: _NotRequired[str]
"""
The documentation URL giving information about the error. No URL is available if
a [`PydanticCustomError`][pydantic_core.PydanticCustomError] is used.
"""
class InitErrorDetails(_TypedDict):
type: str | PydanticCustomError
"""The type of error that occurred, this should be a "slug" identifier that changes rarely or never."""
loc: _NotRequired[tuple[int | str, ...]]
"""Tuple of strings and ints identifying where in the schema the error occurred."""
input: _Any
"""The input data at this `loc` that caused the error."""
ctx: _NotRequired[dict[str, _Any]]
"""
Values which are required to render the error message, and could hence be useful in rendering custom error messages.
Also useful for passing custom error data forward.
"""
class ErrorTypeInfo(_TypedDict):
"""
Gives information about errors.
"""
type: ErrorType
"""The type of error that occurred, this should be a "slug" identifier that changes rarely or never."""
message_template_python: str
"""String template to render a human readable error message from using context, when the input is Python."""
example_message_python: str
"""Example of a human readable error message, when the input is Python."""
message_template_json: _NotRequired[str]
"""String template to render a human readable error message from using context, when the input is JSON data."""
example_message_json: _NotRequired[str]
"""Example of a human readable error message, when the input is JSON data."""
example_context: dict[str, _Any] | None
"""Example of context values."""
class MultiHostHost(_TypedDict):
"""
A host part of a multi-host URL.
"""
username: str | None
"""The username part of this host, or `None`."""
password: str | None
"""The password part of this host, or `None`."""
host: str | None
"""The host part of this host, or `None`."""
port: int | None
"""The port part of this host, or `None`."""
MISSING = Sentinel('MISSING')
"""A singleton indicating a field value was not provided during validation.
This singleton can be used a default value, as an alternative to `None` when it has
an explicit meaning. During serialization, any field with `MISSING` as a value is excluded
from the output.
Example:
```python
from pydantic import BaseModel
from pydantic_core import MISSING
class Configuration(BaseModel):
timeout: int | None | MISSING = MISSING
# configuration defaults, stored somewhere else:
defaults = {'timeout': 200}
conf = Configuration.model_validate({...})
timeout = conf.timeout if timeout.timeout is not MISSING else defaults['timeout']
"""
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff