Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion docs/pkgops-implementation-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ between 2→3 and 3→4; slice 1 is independent and lands first as the low-risk
slice 1 pkgstate::dpkg_selections() [DONE — pkgstate #10, 0.0.1.9]
slice 2 runix native effect-session API [C in common core; critical-path enabler]
slice 3 pkgops package [needs 1 + 2]
slice 4 rctl apt.* surface [needs 3; LAST, per contract §8]
slice 4 rctl apt.* surface [DONE — rctl #12, 0.0.1.8]
```

- **Slice 1** unblocks hold/unhold verification and touches nothing risky. Good
Expand Down Expand Up @@ -356,6 +356,21 @@ Mirrors the `host.*`/`packages.*` pattern just landed. pkgops is a runtime-detec
contract's terminal envelope. Advertised via `rctl capabilities`. Built only once the R
API is stable.

**DONE (2026-08-20, rctl #12, rctl 0.0.1.8).** 18 operations (nine
`apt.<verb>-preview` + nine `apt.<verb>`) in `rctl/R/dispatch.R`, plus
`ERROR_PASSTHROUGH` widened for pkgops's `verb`/`plan_hash`/`status`/
`effect_issued`/`detail`. As-built refinements: authorization is **always machine
mode** (`interactive = FALSE`) — rctl runs non-interactively with no polkit agent,
so a denial or `approval_required` surfaces as a terminal exit-1 envelope, never a
prompt; `--preview` (the system-wide dry-run flag) returns the advisory and opens
no intent; and the apt handlers reference pkgops **lazily** (`getExportedValue`
inside the closure, not `mutation_handler`'s eager `force`) so `operations()` and
`capabilities` still build with pkgops absent. `apt.configure` is nullary
(whole-system set = update/upgrade/dist_upgrade/configure). 68 hermetic tests drive
real pkgops through its own faked seams; proven non-vacuous in CI (the CI also
gained `libjansson-dev` + `pkgops` in the sibling build). Hermetic-only proof, no
new VM run. **Slice 4 was the last slice; the arc is functionally complete.**

---

## 6. Verification ladder (contract §9) and what needs the VM
Expand Down
16 changes: 12 additions & 4 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,18 @@ Priority: **[U]** urgent, **[N]** next, **[L]** later.
(pkgexec #3, runix #67, with the VM-only lifecycle driver in runix-audit-broker
#4). The verification ladder (contract → helper/API → fixture tests → the
disposable-VM gate: dpkg locking, maintainer scripts, interrupted transactions,
package ownership) passed. **Remaining: `pkgops`**, the unprivileged R-facing
layer that previews, obtains the receipt, invokes pkgexec, verifies native state,
and closes the audit outcome. **← current arc.**
8. apt mutation implementation; then gaps 4–6 incrementally.
package ownership) passed. **`pkgops` (the unprivileged R issuer) — done
(2026-08-18):** nine `apt_<verb>_preview()` + nine `apt_<verb>()` that preview,
obtain the receipt, invoke pkgexec, verify native state, and close the audit
outcome; the disposable-VM Part B proof passed (polkit 23/23, §7 gates 68/68).
**`rctl apt.*` (slice 4) — done (2026-08-20, rctl #12, 0.0.1.8):** the arc is
exposed on the CLI (`rctl apt install nginx --json`, always machine mode),
completing the boundary end to end. **← arc functionally complete.**
8. **A0 release of the apt arc.** The read-only stack's A0-dev packaging
(`a0-packaging-plan.md`) does not yet cover `pkgexec` (the privileged `.deb`,
still untagged/unpublished) or `pkgops`; scope their packaging and distribution
— CRAN vs a proper signed apt repo is an **open decision**, and a lot more local
testing is wanted first. Then gaps 4–6 incrementally.

## Validation: the workflow that must be materially better

Expand Down
Loading