\b and \d should be \\b and \\d. qx literals are like qq literals, so \, $ and @ need to be escaped.
And you should get rid of \n in the print statement since the string in $date already has one, or remove the one in $date using chomp( $date );.
You also have a code injection bug in your interpolation of $file which could be solved using String::ShellQuote's shell_quote.
use String::ShellQuote qw( shell_quote );
my @cmd = ( "grep", "-oP", '\bInvoked at: \K[^#]*\d', $file_qfn );
my $cmd = shell_quote( @cmd );
my $date = qx($cmd);
die "Can't spawn shell: $!\n" if $? == -1;
die "Shell killed by signal ".( $? & 0x7F )."\n" ) if $? & 0x7F;
die "Shell exited with error ".( $? >> 8 )."\n" ) if $? >> 8;
chomp( $date );
say $date;
Better yet, we can avoid the shell, and avoiding building a shell command.
use IPC::System::Simple qw( capturex );
my @cmd = ( "grep", "-oP", '\bInvoked at: \K[^#]*\d', $file_qfn );
my $date = capturex( @cmd );
chomp( $date );
say $date;
Buy why run a child process at all?
use File::Slurper qw( read_text );
my $file = read_text( $file_qfn );
my ( $date ) = $file =~ /\bInvoked at: ([^#]*\d)/
or die( "Invocation date not found\n" );
say $date;