Files
pgr/deltas/0.0.4/alpha.4.md
2026-09-24 14:48:17 +02:00

10 KiB

Delta 0.0.4-alpha.4 — skeleton Rust/Cargo workspace

Baseline et version

Baseline attendue : commit opérateur de 0.0.4-alpha.3, réalisé après application de history/0.0.4/alpha.3.md avec statut PASS.

Le hash de ce commit n'est volontairement pas anticipé : le history alpha.3 et le présent delta peuvent être livrés dans le même échange, mais restent deux archives séparées et le delta alpha.4 MUST NOT être appliqué avant le commit de alpha.3.

Version avant application :

0.0.4-alpha.3

Version après application :

0.0.4-alpha.4

Objet

Matérialiser la première specialization technologique prévue par le plan 0.0.4 : un skeleton Rust/Cargo workspace composable avec la fondation 001, les profils 500 + 510, les cinq templates Rust/Cargo existants et leurs guides d'adaptation.

La specification doit rendre explicites les décisions destinataire avant copie, la relation entre VERSION et la version Cargo, les membres du workspace, l'édition/toolchain, les métadonnées, les dépendances/features, Cargo.lock, les lints, les paramètres Rustfmt/Clippy, les artefacts Cargo et la sélection éventuelle des audits de style Rust.

Aucun template Rust/Cargo ni owner normatif n'est modifié dans cette tranche : la spécialisation doit composer les pièces déjà éprouvées sans universaliser leurs valeurs d'exemple.

Scope

REPLACE :

VERSION
README.md
docs/000-README.md
docs/skeletons/000-README.md

ADD :

docs/skeletons/002-RUST_CARGO_WORKSPACE.md
deltas/0.0.4/alpha.4.md

DELETE : aucun.

L'archive delta contient uniquement ces six fichiers complets avec leurs chemins relatifs. Elle ne contient ni history/0.0.4/alpha.3.md, livré séparément pour clôturer la tranche précédente, ni history/0.0.4/alpha.4.md, qui sera produit après la gate opérateur.

Les documents suivants restent inchangés :

docs/rules/220-SKELETONS.md
docs/rules/500-LANGUAGES.md
docs/rules/510-RUST_CARGO.md
docs/templates/001-RUST_CARGO_TOOLING.md
docs/templates/002-CARGO_MANIFESTS.md
docs/validation/002-RUST_STYLE_AUDITS.md
templates/rust-cargo/rustfmt.toml
templates/rust-cargo/clippy.toml
templates/rust-cargo/.cargo/config.toml
templates/rust-cargo/Cargo.toml
templates/rust-cargo/crates/project-core-lib/Cargo.toml

La tranche exécute donc le plan sans REPLAN et sans déplacer les propriétaires existants.

Contenu matérialisé

docs/skeletons/002-RUST_CARGO_WORKSPACE.md :

  • se compose explicitement avec 001-PROJECT_GOVERNANCE_FOUNDATION.md ;
  • sélectionne 500-LANGUAGES.md et 510-RUST_CARGO.md sans absorber leurs règles ;
  • référence les guides 001-RUST_CARGO_TOOLING.md et 002-CARGO_MANIFESTS.md ;
  • identifie exactement les cinq templates Rust/Cargo copiables existants ;
  • rend explicites les décisions de release unit, membres, édition/toolchain, publication, métadonnées, dépendances/features, lockfile, lints, formatage, Clippy et artefacts ;
  • rappelle que 0.1.0, 2024, project-name, project-core-lib, les seuils Clippy et les chemins de build doivent être revus avant adoption ;
  • ne fournit aucun src/lib.rs ou src/main.rs universel ;
  • conserve les audits de style Rust comme option explicitement sélectionnée avec corpus ciblé ;
  • définit une validation Cargo initiale fondée sur cargo metadata, Rustfmt, cargo check et Clippy ;
  • permet aux futurs profils plateforme/framework de s'ajouter après le workspace sans créer un composite artificiel.

Validation opérateur

Après avoir appliqué history/0.0.4/alpha.3.md, committé 0.0.4-alpha.3, puis appliqué le présent delta, depuis la racine du dépôt :

test "$(cat VERSION)" = '0.0.4-alpha.4'
test -f history/0.0.4/alpha.3.md
test -f deltas/0.0.4/alpha.4.md
test -f docs/skeletons/002-RUST_CARGO_WORKSPACE.md
test ! -e history/0.0.4/alpha.4.md

grep -Fx '<!-- version: 10 -->' README.md
grep -Fx '<!-- version: 8 -->' docs/000-README.md
grep -Fx '<!-- version: 3 -->' docs/skeletons/000-README.md
grep -Fx '<!-- version: 1 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md

grep -F '002-RUST_CARGO_WORKSPACE.md' README.md
grep -F '002-RUST_CARGO_WORKSPACE.md' docs/000-README.md
grep -F '002-RUST_CARGO_WORKSPACE.md' docs/skeletons/000-README.md

python3 -B -m unittest discover -s tests -v

python3 -B scripts/audit_markdown_headers.py \
    README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
python3 -B scripts/audit_markdown_tables.py \
    README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
python3 -B scripts/audit_markdown_links.py \
    README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts

python3 -B - <<'PY'
from pathlib import Path
import re
import tomllib

histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
assert histories == {'alpha.1.md', 'alpha.2.md', 'alpha.3.md'}, histories
for name in sorted(histories):
    text = Path('history/0.0.4', name).read_text(encoding='utf-8')
    assert re.search(r'## Statut\s+PASS\s', text), name

skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
assert skeletons == [
    '000-README.md',
    '001-PROJECT_GOVERNANCE_FOUNDATION.md',
    '002-RUST_CARGO_WORKSPACE.md',
], skeletons

text = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
for phrase in (
    '## Applicabilité et composition',
    '## Owners, guides et artefacts sélectionnés',
    '## Décisions destinataire avant copie',
    '## Matérialisation du workspace',
    '### Cargo.lock',
    '### Audits de style facultatifs',
    '## Validation initiale',
    '## Ordre de composition et extensions',
    '## Overrides et exceptions',
    '## Hors scope',
):
    assert phrase in text, phrase

for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
    assert owner in text, owner

for template in (
    'templates/rust-cargo/rustfmt.toml',
    'templates/rust-cargo/clippy.toml',
    'templates/rust-cargo/.cargo/config.toml',
    'templates/rust-cargo/Cargo.toml',
    'templates/rust-cargo/crates/project-core-lib/Cargo.toml',
):
    assert template in text, template

for path in (
    Path('templates/rust-cargo/rustfmt.toml'),
    Path('templates/rust-cargo/clippy.toml'),
    Path('templates/rust-cargo/.cargo/config.toml'),
    Path('templates/rust-cargo/Cargo.toml'),
    Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
):
    with path.open('rb') as stream:
        tomllib.load(stream)

print('Rust/Cargo skeleton audit: clean (alpha.1-alpha.3 PASS baseline, five templates parsed)')
PY

command -v cargo
command -v rustfmt
cargo --version
rustc --version
rustfmt --version
cargo clippy --version

tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT
mkdir -p "$tmp/.cargo" "$tmp/crates/smoke-core-lib/src"
cp templates/rust-cargo/Cargo.toml "$tmp/Cargo.toml"
cp templates/rust-cargo/rustfmt.toml "$tmp/rustfmt.toml"
cp templates/rust-cargo/clippy.toml "$tmp/clippy.toml"
cp templates/rust-cargo/.cargo/config.toml "$tmp/.cargo/config.toml"
cp templates/rust-cargo/crates/project-core-lib/Cargo.toml "$tmp/crates/smoke-core-lib/Cargo.toml"
printf '1.2.3\n' > "$tmp/VERSION"

python3 -B - "$tmp" <<'PY'
from pathlib import Path
import sys

root = Path(sys.argv[1])

replacements = {
    root / 'Cargo.toml': (
        ('# file: templates/rust-cargo/Cargo.toml', '# file: Cargo.toml'),
        ('members = ["crates/project-core-lib"]', 'members = ["crates/smoke-core-lib"]'),
        ('version = "0.1.0"', 'version = "1.2.3"'),
    ),
    root / 'rustfmt.toml': (
        ('# file: templates/rust-cargo/rustfmt.toml', '# file: rustfmt.toml'),
    ),
    root / 'clippy.toml': (
        ('# file: templates/rust-cargo/clippy.toml', '# file: clippy.toml'),
    ),
    root / '.cargo/config.toml': (
        ('# file: templates/rust-cargo/.cargo/config.toml', '# file: .cargo/config.toml'),
        ('../builds/project-name/target', 'target-smoke'),
    ),
    root / 'crates/smoke-core-lib/Cargo.toml': (
        ('# file: templates/rust-cargo/crates/project-core-lib/Cargo.toml', '# file: crates/smoke-core-lib/Cargo.toml'),
        ('name = "project-core-lib"', 'name = "smoke-core-lib"'),
    ),
}

for path, pairs in replacements.items():
    text = path.read_text(encoding='utf-8')
    for old, new in pairs:
        assert old in text, (path, old)
        text = text.replace(old, new)
    path.write_text(text, encoding='utf-8')

for path in root.rglob('*'):
    if path.is_file() and path.name != 'Cargo.lock':
        text = path.read_text(encoding='utf-8')
        assert 'project-name' not in text, path
        assert 'project-core-lib' not in text, path
PY

cat > "$tmp/crates/smoke-core-lib/src/lib.rs" <<'RS'
//! Minimal crate used to validate the PGR Rust/Cargo templates.

/// Returns the deterministic smoke value.
pub fn smoke_value() -> u8 {
    return 1;
}
RS

(
    cd "$tmp"
    cargo metadata --format-version 1 --no-deps >/dev/null
    cargo fmt --all -- --check
    cargo check --workspace
    cargo clippy --workspace --all-targets --all-features -- -D warnings
)

rm -rf "$tmp"
trap - EXIT

git diff --check
git add VERSION README.md docs/000-README.md \
    docs/skeletons/000-README.md \
    docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
    deltas/0.0.4/alpha.4.md
git diff --cached --check
git status --short

Revue opérateur

En complément des commandes, vérifier que :

  • 002 reste une specialization composable de 001 et ne redéfinit pas les owners généraux ;
  • les cinq templates sont référencés comme artefacts à adapter, jamais comme valeurs universelles ;
  • la politique Cargo.lock, les membres, dépendances/features, métadonnées et éventuelles exceptions de lints/safety restent des décisions explicites du projet ;
  • les audits Rust facultatifs ne sont ni copiés ni exécutés sans sélection de leur convention et de leur corpus ;
  • aucune règle Java/Android/Web/JNI/Tauri ou autre plateforme/framework n'entre dans la tranche ;
  • l'instanciation temporaire prouve l'adoption minimale des templates sans ajouter de workspace Rust au dépôt PGR.

Transition

PASS : produire history/0.0.4/alpha.4.md, l'appliquer puis committer 0.0.4-alpha.4. La tranche suivante prévue par le plan est 0.0.4-beta.1, consacrée à la réconciliation interne de la release : ownership, liens, index, duplication normative, valeurs d'exemple, limites des audits et confirmation des domaines différés.

FAIL : rester dans le scope de alpha.4 via alpha.4.fix.1 sauf si l'instanciation démontre qu'un template ou une décision normative existante est insuffisante, auquel cas déclencher le REPLAN prévu par le plan.