Skip to content

Commit c75e33a

Browse files
committed
docs(plan): the task dependency graph, and what each of the nine views decided
1 parent 1c79143 commit c75e33a

1 file changed

Lines changed: 36 additions & 0 deletions

File tree

.agents/docs/2026-08-29-build-rule-package-spec.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,42 @@ before, once for the directive cache and once for the advisory channel.
569569

570570
---
571571

572+
## 9a. The work, and what depends on what
573+
574+
The pieces below were sequenced by what each one makes verifiable, not by size.
575+
576+
```
577+
I1 module name from source ─┬─► I3 collision refused
578+
│ (I1 makes new collisions reachable;
579+
│ they must not ship apart)
580+
└─► I2 package-name constraint deleted
581+
(a consequence, not a task)
582+
583+
B1 build-only subtree ──────► B2 rule imports its build deps
584+
(the fix that stops (needs a resolved subtree to order)
585+
the leak)
586+
587+
M0 six leaf modules ────────► M1..M3 (blocked on the M0 measurement)
588+
589+
engine (all of the above) ──► release ──► ecosystem rule packages
590+
(they cannot be used by anyone
591+
until the engine ships)
592+
```
593+
594+
Nine views of the same change, each with the thing it actually decided:
595+
596+
| View | What it decided here |
597+
|---|---|
598+
| **Architecture** | The section/request split (3.3). Two orthogonal axes rather than two spellings of one, which is what makes the protobuf case expressible at all. |
599+
| **Stability** | I1 and I3 ship together. Decoupling the module name from the package name is what makes a new collision reachable, so the refusal cannot lag behind it by a release. |
600+
| **Simplicity** | B1 replaced a per-edge predicate with forward reachability, and the dual-role case then needed no special case. The diff removes a rule rather than adding one. |
601+
| **User experience** | Every new refusal names both sides. The collision names two packages and two paths because with one module name shared they are the only way to tell them apart. |
602+
| **Compatibility** | Measured, not argued: `grpcgen`, the only rule package in the index, registers the identical module name before and after, and its build is byte-identical. `[dependencies]` carrying `tools`/`host-module` is untouched. |
603+
| **Cross-platform** | I1 exists *because* the three compiler families disagreed. The e2e cannot assert through the successful import, since GCC resolves by the declared name regardless — so it asserts on filenames, which every platform produces. |
604+
| **Consistency** | `prepare.cppm:3924` already stated "module names are authored API"; `:4780` was the only place contradicting it. The change is a return, not an exception. |
605+
| **Silent upgrade** | No manifest key was added (I7). A package written for the old engine builds unchanged; a package written for the new one fails to *compile* on an old engine rather than silently losing semantics, which is what the protocol version already guarantees. |
606+
| **Test coverage** | Each assertion was observed failing against the previous behaviour before it was kept. That is what caught two wrong claims in this document. |
607+
572608
## 10. The framework in one view
573609

574610
Four layers. The only thing an author writes is L1, and what L1 emits is either

0 commit comments

Comments
 (0)