package hostbox import ( "context" "path" "strings" ) // IntendRole commits the empty child's exact parent and reserved name before // mkdir. Only Reserve can turn it into execution authority. func (j *LaunchJournal) IntendRole(ctx context.Context, r LaunchReservation) error { if j == nil { return ErrUnsupported } if j.remote != nil { out, err := journalCall(ctx, j.remote, JournalRequest{Op: "intend", Reservation: r}) _ = out return err } if r.NeverIntended || r.ID == "" || r.Role == "" || r.InvocationID == "" || r.Inputs == "" || r.State != "" || r.PID != 0 || r.ProcessStart != "" || r.Group.Device != 0 || r.Group.Inode != 0 || r.Group.InvocationID != r.InvocationID || r.Executable.Device == 0 || r.Executable.Inode == 0 || r.Parent.Device == 0 || r.Parent.Inode == 0 || !managedName(r.Parent.RelativePath) || path.Dir(r.Group.RelativePath) != r.Parent.RelativePath || !strings.HasPrefix(path.Base(r.Group.RelativePath), "role-") || !managedName(r.Group.RelativePath) { return ErrUnsupported } return j.mutate(ctx, r.Target, func(in *LaunchInventory) error { parent := false for _, g := range in.Groups { if g == r.Parent { parent = true } } if !parent { return ErrChanged } for _, old := range in.Reservations { if old.ID == r.ID || old.Group.RelativePath == r.Group.RelativePath { return ErrChanged } } for _, g := range in.Groups { if g.RelativePath == r.Group.RelativePath { return ErrChanged } } r.State = "intended" in.Reservations = append(in.Reservations, r) return nil }) }