Add Remote session foundations and feasibility checks

Add opt-in Tentacle protocol 1.1, explicit remote grants, lifecycle IPC and expiring core leases in both SDKs. Revoke access before update preparation, including failed updates.

Add transient secret entries, shared Braille cell export and isolated Xorg recovery experiments with focused tests and documented limitations. Production consent, desktop services and live interoperability remain pending.
This commit is contained in:
ak47 committed 2026-11-03 22:33:26 -05:00
1 parent a47253d697
commit 573d15d7b4
45 files changed
+3634 -80

No files matched your search

+17 -3
View File
@@ -24,6 +24,8 @@ import (
"time"
"github.com/pelletier/go-toml/v2"
"git.stormux.org/storm/cthulhu/internal/tentaclewire"
)
const maxPackageBytes = 32 << 20
@@ -197,7 +199,7 @@ func prepare_package(ctx context.Context, root string, repository Repository, lo
if packageManifest.FormatVersion != manifest.FormatVersion || packageManifest.ID != manifest.ID || packageManifest.Version != manifest.Version || packageManifest.Name != manifest.Name || !slices.Equal(packageManifest.Capabilities, manifest.Capabilities) {
return nil, errors.New("Package identity, version or permissions disagree with the catalog; refresh the repository.")
}
if packageManifest.Runtime != "native" || !slices.Contains(packageManifest.Platforms, runtime.GOOS) || packageManifest.Protocol.Major != 1 || packageManifest.Protocol.Minor != 0 {
if packageManifest.Runtime != "native" || !slices.Contains(packageManifest.Platforms, runtime.GOOS) || packageManifest.Protocol.Major != 1 || (packageManifest.Protocol.Minor != 0 && packageManifest.Protocol.Minor != 1) {
return nil, errors.New("Package runtime, platform or protocol is unsupported by this reader.")
}
presentation := slices.Contains(packageManifest.Capabilities, "presentation")
@@ -213,7 +215,13 @@ func prepare_package(ctx context.Context, root string, repository Repository, lo
if readerSettings {
expectedAPIs = append(expectedAPIs, "reader-settings")
}
if readerSettings && !interactive || interactive && !presentation || len(packageManifest.Capabilities) != len(expectedAPIs)-1 || !slices.Equal(packageManifest.APIs, expectedAPIs) {
valid := false
if packageManifest.Protocol.Minor == 0 {
valid = !(readerSettings && !interactive || interactive && !presentation) && len(packageManifest.Capabilities) == len(expectedAPIs)-1 && slices.Equal(packageManifest.APIs, expectedAPIs)
} else {
valid = tentaclewire.ValidNegotiation(1, packageManifest.APIs, packageManifest.Capabilities)
}
if !valid {
return nil, errors.New("Package requires unsupported APIs or permissions.")
}
if len(packageManifest.EntryPoint) == 0 || len(packageManifest.EntryPoint) > 32 || !package_path(packageManifest.EntryPoint[0]) {
@@ -246,7 +254,13 @@ func prepare_package(ctx context.Context, root string, repository Repository, lo
prepared.directory = final
program := slices.Clone(packageManifest.EntryPoint)
program[0] = filepath.Join(final, filepath.FromSlash(program[0]))
prepared.Entry = Entry{ID: PackageID(repository, localID), LocalID: localID, Name: manifest.Name, Version: manifest.Version,
remoteGrants := []string{}
for _, grant := range tentaclewire.RemoteGrants() {
if slices.Contains(packageManifest.Capabilities, grant) {
remoteGrants = append(remoteGrants, grant)
}
}
prepared.Entry = Entry{SessionEvents: packageManifest.Protocol.Minor == 1, RemoteGrants: remoteGrants, ID: PackageID(repository, localID), LocalID: localID, Name: manifest.Name, Version: manifest.Version,
Program: program, Directory: final, Presentation: presentation, Interaction: interactive, ReaderSettings: readerSettings, Repository: repository.URL, RepositoryID: repository.ID,
RepositoryRevision: repository.Revision, PackageDirectory: final, PackageSHA256: release.SHA256}
if err := ValidateEntries([]Entry{prepared.Entry}); err != nil {