feat: activation on demand — detect a package this project wants, and repeat a decision the operator already made #90
Labels
No labels
code-review
correctness
dos
performance
security
severity/high
severity/low
severity/medium
tech-debt
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
h-dv/code-index#90
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Spec:
_prdoc/specs/86-activation-on-demand.md— the filename's number is a collision with the existing #86 and will be renamed to this issue's number once the in-flight lanes stop reading it.The problem
A project holds
.xamlfiles. The operator installed and enabled the xaml package for a DIFFERENT project last week. Today they open this one, get text-only rows, and nothing tells them a package they already trust and already run would claim these files. The product knows every fact needed to say so and says none of them.plugin_add(v0.25.0) made the ACT easy. It did not make the NEED visible, and an agent cannot ask for what it has not been told exists.Phase A — detect and offer (implemented, in review)
Detection is entirely local: a package in the operator's store whose manifest claims an extension this project actually holds files for, and whose digest this project's
ApprovalRecorddoes not approve. No network, no registry. The census is the same populationsymbol_blind_extensionsreports, so the two cannot disagree.project_overviewgainsactivation_available(three-state, likepackage_set_consulted) andactivation_auto_enabled.The line: the first grant is a decision, the second is a repetition
"Installing grants nothing —
enableis the grant" is stated in the product's docs and in the v0.25.0 release notes an operator has already read. So a silent enable is permitted only on capability parity:Where (3) fails there is no parity basis and the row stays an offer. The first grant of a package remains a human decision, on every machine, forever.
Forbidden absolutely
.cipnever auto-enables. It is the one input any contributor to a repository can write, and S2 exists because cloning a repo must not activate code.Round 2 — what the adversarial review found
Two HIGH defects, both reproduced, sharing one root cause: the approval record stores no negative decision and no provenance for a grant.
plugin disablewas silently undone within minutes. No tombstone, so the next pass re-granted — andauto_enableruns twice per process, the daemon idle-exits at 30 min, and under--no-daemonthe next invocation re-grants. We SHIPundo_commandin the disclosure, so this made a published promise false. A disclosure that names an undo which does not hold is worse than silence.Fixes in flight:
ApprovalRecord.declined(tombstone),ParityGrant.basis_digest,Approval.auto_enabled_from, plus basis-record identity verification and narrowest-basis selection.Phase B — lazy runtime start (not started)
Approved packages start at daemon startup. Phase B starts a package's worker on first demand and idles it out. Phase A deliberately keeps "is it approved" and "is it running" as separate questions in every payload it adds, so Phase B changes only the second.
Relationship to the epic
Independent of #75's chain: it makes an ALREADY-approved package reach a new project, and changes nothing about what a package can do. It does not advance #84's genericity proof.
Shipped in v0.26.0
Detection is local: a package in the operator's store whose manifest claims an extension this project actually holds files for, and whose digest this project has not approved. The census is the same population
symbol_blind_extensionsreports, so the two cannot disagree.A silent enable requires the operator to have already approved that digest in another project, and writes the intersection of what they granted there with what the package requests now — never wider. Where there is no basis the row is offered, not enabled: the first grant of a package stays a human decision on every machine. An in-tree
.cipnever auto-enables, because cloning a repository must not activate code.What the adversarial review caught, and it was right twice
plugin disablewas silently undone within minutes.cmd_disablecleared the row and left no tombstone, so the next pass re-granted it — andauto_enableruns twice per process, the daemon idle-exits at 30 minutes, and under--no-daemonthe next invocation re-grants. We shipundo_commandin the disclosure, so this made a published promise false.ApprovalRecord.declinedis the tombstone, andset/cleardeliberately do not touch it, because a tombstone the machine can clear is not a tombstone.Live on the installed build
Reported as a measurement — an empty list, not an absent field — which is the distinction that makes "nothing to offer here" different from "this build does not answer".
One defect this shipped with, found and fixed in the same cycle
The approval record's key was derived from
canonicalize()'s output when the project directory resolved and the raw path when it did not — two spellings of one project on Windows. Since that key is the record's filename, any moment a project directory was unresolvable (a disconnected share, an unmounted volume) the lookup computed a different key and every grant appeared to vanish, returning when the share reconnected. Corrected with a migration that moves existing records on first use, so no operator is asked to re-approve anything.Spec:
_prdoc/specs/90-activation-on-demand.md(renamed from86-— it had been filed under another issue's number).