portage-ng / handbook
PDF GitHub

Policy by example

Curated overlay specimens for learning Gentoo domain policy. Each entry is a story (what policy is being exercised), not a full regression matrix — for all 80 cases see Documentation/Tests/README.md.

Run a single scenario after loading the overlay (see Chapter 25):

make test-overlay

Or open the per-test README under Documentation/Tests/testNN/.

Suggested reading order

Work top-to-bottom the first time; afterwards jump via cards or the map.

Step Test Policy card One-line lesson
1 test01 Install / Run DEPEND + RDEPEND become :install / :run obligations
2 test02 Dependency Newest eligible version wins by default
3 test12 Visibility Keyword reject → positive assumption
4 test09 Assumptions Missing package → negative assumption
5 test13 Dependency = pin selects exactly one version
6 test55 Dependency Constraints intersect to one domain
7 test14 USE USE-conditional deps gate the body
8 test33 USE Bracketed [flag] becomes build_with_use
9 test52 USE Shared child merges USE from two parents
10 test40 REQUIRED_USE Package-local || USE constraint
11 test49 REQUIRED_USE Soft (+) loses to hard REQUIRED_USE
12 test20 Choice || picks one admitted arm
13 test60 Choice / Blocker Ranking + soft blocker prefer newer arm
14 test26 Blocker Hard !! forbids co-install
15 test41 Slots Explicit :slot filters candidates
16 test48 Slots Same slot, two versions → conflict
17 test03 Cycle Self-dep → benign prover cycle-break
18 test66 Run PDEPEND resolved in the same prove pass
19 test74 Install Constraint can force a downgrade
20 test76 USE / Install Wrong installed USE → rebuild

Specimens

test01

Cards: Install, Run, Target
Story: Four-package DAG with compile- and runtime edges; plan orders leaves first and may parallelize independent installs.
Read: Documentation/Tests/test01/README.md

test02

Cards: Dependency
Story: Two versions available; default selection is the newest eligible.
Read: test02/README.md

test03

Cards: Cycle
Story: Direct self-DEPEND; proof completes with a benign assumed(rule(…:install)) cycle-break (exit 1 if alone).
Read: test03/README.md

test05

Cards: Cycle
Story: Self-dep on both compile and runtime legs; the compile leg needs a cycle-break assumption on os:install, the runtime leg resolves via the install/run action split.
Read: test05/README.md

test06

Cards: Cycle
Story: Indirect compile-time cycle; dissolved by the install/run action split — no cycle-break assumption needed (unlike self-dep test03).
Read: test06/README.md

test09

Cards: Assumptions, Dependency
Story: Non-existent compile-time dep → negative non_existent / missing dependency assumption.
Read: test09/README.md

test10

Cards: Run, Assumptions
Story: Same as test09 but in RDEPEND / :run scope.
Read: test10/README.md

test12

Cards: Visibility, Assumptions
Story: Unstable keyword; acceptance is a positive domain assumption with suggestion(accept_keyword, …).
Read: test12/README.md

test13

Cards: Dependency
Story: =cat/pkg-ver pin; only that version is admitted.
Read: test13/README.md

test14

Cards: USE
Story: lib? ( … ) omitted when lib is disabled.
Read: test14/README.md

test17

Cards: Choice
Story: ^^ exactly-one-of among OS flavours.
Read: test17/README.md

test20

Cards: Choice
Story: Classic || ( … ) any-of at compile time.
Read: test20/README.md

test23

Cards: Choice
Story: ?? at-most-one-of cardinality.
Read: test23/README.md

test26

Cards: Blocker
Story: Strong !! blocker interacting with an any-of group.
Read: test26/README.md

test27

Cards: Blocker, Assumptions
Story: Weak ! blocker; may record a positive blocker assumption.
Read: test27/README.md

test33

Cards: USE
Story: Positive bracketed USE dep [linux] forces child USE.
Read: test33/README.md

test35

Cards: USE
Story: Equality USE dep [linux=] ties parent/child flag state.
Read: test35/README.md

test40

Cards: REQUIRED_USE
Story: Standalone package REQUIRED_USE="|| ( linux darwin )".
Read: test40/README.md

test41

Cards: Slots
Story: Explicit slot operator :1.
Read: test41/README.md

test42

Cards: Slots
Story: Wildcard :* admits any slot (newest preferred).
Read: test42/README.md

test43

Cards: Slots
Story: Slot operator := (equality / rebuild binding).
Read: test43/README.md

test47

Cards: Cycle
Story: Three-way dependency cycle; resolved without any break — the install/run action split dissolves it.
Read: test47/README.md

test48

Cards: Slots, Assumptions
Story: Same slot, incompatible versions → slot conflict (negative).
Read: test48/README.md

test49

Cards: REQUIRED_USE, USE
Story: Parent soft [feature_z(+)] vs child REQUIRED_USE="!feature_z".
Read: test49/README.md

test50

Cards: Install, Run
Story: Compile dep’s RDEPEND must still appear in the plan.
Read: test50/README.md

test51

Cards: Assumptions, REQUIRED_USE
Story: USE dep vs REQUIRED_USE contradiction (negative / blocking).
Read: test51/README.md

test52

Cards: USE
Story: Two parents force different flags on one os; single install with merged USE.
Read: test52/README.md

test55

Cards: Dependency
Story: Direct >3 and <6 intersect; one version selected.
Read: test55/README.md

test59

Cards: Choice
Story: Regression lock for || arm selection vs emerge.
Read: test59/README.md

test60

Cards: Choice, Blocker
Story: !<windows-2.0 + || → prefer windows-2.0 (newest admitted).
Read: test60/README.md

test61

Cards: Cycle, USE
Story: Mutual recursion with bracketed USE must terminate.
Read: test61/README.md

test63

Cards: REQUIRED_USE
Story: OpenMPI-style REQUIRED_USE loop; must not timeout.
Read: test63/README.md

test65

Cards: Install, USE
Story: build_with_use reinstall / update semantics vs VDB.
Read: test65/README.md

test66

Cards: Run
Story: Transitive PDEPEND resolved in-prove (always enabled).
Read: test66/README.md

test67

Cards: Install
Story: BDEPEND is build-only; distinct from DEPEND in obligations.
Read: test67/README.md

test68

Cards: Slots
Story: Same CN, different slots may co-install.
Read: test68/README.md

test69

Cards: Dependency
Story: Operator >=.
Read: test69/README.md

test70

Cards: Dependency
Story: Operator ~ (revision match).
Read: test70/README.md

test71

Cards: Target
Story: Fetch-only action path.
Read: test71/README.md

test74

Cards: Install, Dependency
Story: Installed newer version; atom forces downgrade.
Read: test74/README.md

test76

Cards: USE, Install
Story: Installed with wrong USE → rebuild / newuse.
Read: test76/README.md

test78

Cards: Target
Story: --onlydeps / skip target, install deps only.
Read: test78/README.md

test79

Cards: Run, Cycle
Story: PDEPEND cycle A↔B; resolved via the proof-obligation hook with no assumptions — PDEPEND is never disabled to avoid it.
Read: test79/README.md

test80

Cards: Dependency
Story: Operator <=.
Read: test80/README.md

PLUnit companions

Overlay stories cover end-to-end policy. For isolated primitives, prefer PLUnit in Source/Test/unittest.pl:

Area Where to look
Version parse / PMS order begin_tests version / compare groups
Version domains / meet domain-related tests + Chapter 10
EAPI / md5-cache extract md5cache_validate/0
GLSA match / @security begin_tests(glsa)

These are not substitutes for the overlay curriculum; they back the atoms the cards mention.