Files
pgr/deltas/0.0.3/alpha.4.md
2026-09-24 09:50:33 +02:00

8.7 KiB

Delta 0.0.3-alpha.4 — manifests Cargo workspace et membre

Baseline et version

Baseline : 0.0.3-alpha.3, avec history/0.0.3/alpha.3.md appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.

Version avant application :

0.0.3-alpha.3

Version après application :

0.0.3-alpha.4

Objet

Fournir les deux manifests Cargo prévus dans le plan après son REPLAN SPLIT : un workspace virtuel à release commune et une crate bibliothèque membre. Les sections d'héritage, les lints Rust/Clippy communs, la version de release et le périmètre des dépendances doivent être compréhensibles sans figer les identités KSP/Games ni une liste de dépendances tierces.

Le manifest racine reprend les trois lints Rust et les 18 niveaux Clippy effectivement communs aux deux projets. Il déclare un bloc [workspace.dependencies] initialement vide. Le membre hérite explicitement des métadonnées présentes et des lints par [lints] workspace = true. La documentation distingue l'adaptation ordinaire d'une exception FFI locale, qui ne peut combiner cet héritage avec des lints locaux dans une même crate. La version 0.1.0 et le nom project-core-lib sont des exemples à remplacer, pas des valeurs de PGR ou d'un projet tiers.

Le plan vivant reçoit deux corrections factuelles : PGR possède désormais plus de deux utilitaires Python et la famille énumère cinq responsabilités, et non quatre. Ces corrections n'altèrent aucun delta ni history précédent.

Scope

REPLACE :

VERSION
docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md
docs/templates/001-RUST_CARGO_TOOLING.md

ADD :

templates/rust-cargo/Cargo.toml
templates/rust-cargo/crates/project-core-lib/Cargo.toml
docs/templates/002-CARGO_MANIFESTS.md
deltas/0.0.3/alpha.4.md

DELETE : aucun.

L'archive contient uniquement ces fichiers complets. Aucun fichier source Rust, history alpha.4, suppression, dépendance de build de PGR ou version tierce n'est introduit.

Validation opérateur

Après application sur le commit alpha.3 :

test "$(cat VERSION)" = '0.0.3-alpha.4'
git cat-file -e HEAD:history/0.0.3/alpha.3.md
test -f history/0.0.3/alpha.3.md
test ! -e history/0.0.3/alpha.4.md
test -f deltas/0.0.3/alpha.4.md

python3 -B - <<'PY'
from pathlib import Path
import json
import shutil
import subprocess
import tempfile
import tomllib

source = Path('templates/rust-cargo')
root_file = source / 'Cargo.toml'
member_file = source / 'crates/project-core-lib/Cargo.toml'
root = tomllib.loads(root_file.read_text(encoding='utf-8'))
member = tomllib.loads(member_file.read_text(encoding='utf-8'))
assert root['workspace']['resolver'] == '3'
assert root['workspace']['members'] == ['crates/project-core-lib']
assert root['workspace']['package']['version'] == '0.1.0'  # Explicit example.
assert root['workspace']['package']['edition'] == '2024'
assert root['workspace']['package']['publish'] is False
assert root['workspace']['dependencies'] == {}
assert root['workspace']['lints']['rust'] == {
    'missing_docs': 'warn', 'unreachable_pub': 'deny', 'unsafe_code': 'forbid'
}
clippy = root['workspace']['lints']['clippy']
assert len(clippy) == 18 and clippy['implicit_return'] == 'deny'
assert clippy['needless_return'] == 'allow' and clippy['unwrap_used'] == 'deny'
assert member['package']['name'] == 'project-core-lib'
for field in ('version', 'edition', 'publish'):
    assert member['package'][field] == {'workspace': True}, field
assert member['dependencies'] == {} and member['lints'] == {'workspace': True}
for path in (root_file, member_file):
    lines = path.read_text(encoding='utf-8').splitlines()
    assert lines[:2] == [f'# file: {path.as_posix()}', '# version: 1'], path
print('Cargo manifest TOML audit: clean (2 file(s))')

if shutil.which('cargo') is None:
    print('Cargo workspace smoke: toolchain unavailable; TOML audit only')
else:
    with tempfile.TemporaryDirectory(prefix='pgr-cargo-manifests-') as folder:
        workspace = Path(folder)
        crate = workspace / 'crates/project-core-lib'
        (crate / 'src').mkdir(parents=True)
        shutil.copy2(root_file, workspace / 'Cargo.toml')
        shutil.copy2(member_file, crate / 'Cargo.toml')
        (crate / 'src/lib.rs').write_text(
            '//! Minimal template check.\n\n/// Return one.\n'
            'pub fn value() -> u8 {\n    return 1;\n}\n', encoding='utf-8'
        )
        command = ['cargo', 'metadata', '--manifest-path', str(workspace / 'Cargo.toml'),
                   '--format-version', '1', '--no-deps', '--offline']
        result = subprocess.run(command, cwd=workspace, text=True,
                                capture_output=True, check=True)
        package = json.loads(result.stdout)['packages'][0]
        assert package['name'] == 'project-core-lib'
        assert package['version'] == '0.1.0' and package['edition'] == '2024'
        subprocess.run(['cargo', 'check', '--workspace', '--offline'],
                       cwd=workspace, check=True)
        if subprocess.run(['cargo', 'clippy', '--version'], capture_output=True).returncode == 0:
            subprocess.run(['cargo', 'clippy', '--workspace', '--all-targets',
                            '--all-features', '--offline', '--', '-D', 'warnings'],
                           cwd=workspace, check=True)

        # Inherited forbid must reject unsafe code before a local FFI exception.
        (crate / 'src/lib.rs').write_text(
            '//! Minimal FFI exception check.\n\n/// Return one.\n'
            'pub fn value() -> u8 {\n'
            '    let value: u8 = 1;\n    let ptr: *const u8 = &value;\n'
            '    unsafe { return *ptr; }\n}\n', encoding='utf-8'
        )
        rejected = subprocess.run(['cargo', 'check', '--workspace', '--offline'],
                                  cwd=workspace, capture_output=True, text=True)
        assert rejected.returncode != 0 and 'unsafe' in rejected.stderr

        # Cargo must accept a local lint table in place of inheritance.
        local = member_file.read_text(encoding='utf-8').replace(
            '[lints]\nworkspace = true\n',
            '[lints.rust]\nmissing_docs = "warn"\n'
            'unreachable_pub = "deny"\nunsafe_code = "allow"\n\n'
            '[lints.clippy]\n' + ''.join(
                f'{name} = {json.dumps(level)}\n' for name, level in clippy.items()
            )
        )
        assert '[lints.rust]' in local and '[lints]\nworkspace = true' not in local
        (crate / 'Cargo.toml').write_text(local, encoding='utf-8')
        subprocess.run(['cargo', 'check', '--workspace', '--offline'],
                       cwd=workspace, check=True)
    print('Cargo workspace smoke: clean (inherited and local lints)')
PY

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

files = [Path(name) for name in ('README.md', 'RULES.md', 'ROADMAP.md', 'CHANGELOG.md')]
for directory in ('docs', 'deltas', 'history', 'prompts'):
    files.extend(Path(directory).rglob('*.md'))
files = sorted(set(files))
for path in files:
    lines = path.read_text(encoding='utf-8').splitlines()
    assert len(lines) >= 2 and lines[0] == f'<!-- file: {path.as_posix()} -->', path
    assert re.fullmatch(r'<!-- version: [1-9][0-9]* -->', lines[1]), path
print(f'Markdown header audit: clean ({len(files)} file(s))')
PY

git diff --check
git add VERSION docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md \
    docs/templates/001-RUST_CARGO_TOOLING.md docs/templates/002-CARGO_MANIFESTS.md \
    templates/rust-cargo/Cargo.toml templates/rust-cargo/crates/project-core-lib/Cargo.toml \
    deltas/0.0.3/alpha.4.md
git diff --cached --check
git status --short

Scope attendu avant ajout du history : les trois REPLACE et les quatre ADD ci-dessus. Revue opérateur : vérifier que le manifest membre hérite seulement des champs racine présents, que les lints Clippy sont ceux des deux corpus et que la version d'exemple ainsi que le nom de crate doivent être remplacés lors d'une adoption réelle. Si Cargo n'est pas disponible dans l'environnement de PGR, le smoke workspace est indiqué comme non exécuté et le parsing TOML reste la preuve locale ; l'adoption dans un projet Rust doit exécuter sa propre gate Cargo.

Transition

PASS

Fournir séparément history/0.0.3/alpha.4.md avec les sorties réellement observées, l'appliquer et committer la tranche avant le delta alpha.5 relatif aux headers Markdown.

FAIL

Consigner le défaut dans le history, puis corriger manifests ou instructions dans alpha.4.fix.1 sauf besoin justifié d'un nouveau REPLAN.