PAX
view release on metacpan or search on metacpan
lib/PAX/Gatekeeper.pm view on Meta::CPAN
};
}
sub _check_backlog_approved_sows {
my ($self) = @_;
my $path = "$self->{root}/project/BACKLOG.md";
my $content = _slurp($path);
my $ok = $content =~ /\| SOW-01 \|/ && $content =~ /\| SOW-02 \|/ && $content !~ /\| SOW-03 \|/;
return {
id => 'approved_sows_indexed',
description => 'Backlog indexes approved SOW-01 and SOW-02 only',
status => $ok ? 'passed' : 'blocked',
evidence => 'project/BACKLOG.md',
};
}
sub _check_docker_pin {
my ($self) = @_;
my $content = _slurp("$self->{root}/Dockerfile");
return {
id => 'pinned_perl_baseline',
description => 'Dockerfile pins the Perl 5.42.0 baseline image',
status => $content =~ /^FROM\s+perl:5\.42\.0\b/m ? 'passed' : 'blocked',
evidence => 'Dockerfile',
};
}
sub _check_cli_surface {
my ($self) = @_;
my $content = _slurp("$self->{root}/lib/PAX/CLI.pm");
my @missing = grep { $content !~ /if \(\$command eq '\Q$_\E'\)/ } ('build', 'run');
my @extra = grep { $content =~ /if \(\$command eq '\Q$_\E'\)/ } qw(
capture inspect hir compile diff bench bench-matrix run-native corpus core-suite
cpan-matrix dispatch profile why-not trace-guards gatekeeper app-build app-start
app-run app-stop standalone-build standalone-run standalone-inspect standalone-extract
standalone-why-not standalone-native-run
);
return {
id => 'cli_sow03_surface',
description => 'Public CLI includes only build and run; diagnostics remain internal implementation APIs',
status => (@missing || @extra) ? 'blocked' : 'passed',
evidence => @missing ? 'missing: ' . join(', ', @missing) : (@extra ? 'extra: ' . join(', ', @extra) : 'lib/PAX/CLI.pm'),
};
}
sub _check_whole_program_app_image {
my ($self) = @_;
my @missing;
push @missing, 'app_image_builder' if !-f "$self->{root}/lib/PAX/AppImage.pm";
push @missing, 'app_server_runtime' if !-f "$self->{root}/lib/PAX/AppServer.pm";
push @missing, 'paxfile_loader' if !-f "$self->{root}/lib/PAX/Paxfile.pm";
push @missing, 'project_paxfile' if !-f "$self->{root}/paxfile.yml";
push @missing, 'app_image_test' if !-f "$self->{root}/t/app_image.t";
push @missing, 'embedded_asset_fixture' if !-f "$self->{root}/t/fixtures/app_assets/banner.txt";
my $cli = _slurp("$self->{root}/lib/PAX/CLI.pm");
my $app_image = _slurp("$self->{root}/lib/PAX/AppImage.pm");
push @missing, 'public_build_command' if $cli !~ /if \(\$command eq 'build'\)/;
push @missing, 'public_run_command' if $cli !~ /if \(\$command eq 'run'\)/;
push @missing, 'asset_build_flags' if $cli !~ /--asset/ || $cli !~ /--asset-dir/;
push @missing, 'paxfile_cli_flags' if $cli !~ /--paxfile/ || $cli !~ /--no-paxfile/;
push @missing, 'asset_embedding_runtime' if $app_image !~ /pax_assets/ || $app_image !~ /PAX_EMBEDDED_ASSET_ROOT/;
return {
id => 'whole_program_app_image_runtime',
description => 'Whole-program Perl entrypoints can be built from paxfile.yml into PAX app images with embedded assets and run through a preloaded subsystem',
status => @missing ? 'blocked' : 'passed',
evidence => @missing ? 'missing: ' . join(', ', @missing) : 'PAX::AppImage/PAX::AppServer',
};
}
sub _check_benchmark_matrix_command {
my ($self) = @_;
my $content = _slurp("$self->{root}/lib/PAX/CLI.pm");
return {
id => 'full_benchmark_execution',
description => 'Benchmark matrix has an executable CLI path',
status => $content =~ /bench-matrix/ ? 'passed' : 'blocked',
evidence => 'PAX::BenchmarkMatrix t/benchmark_matrix.json',
};
}
sub _check_validation_matrix {
my ($self) = @_;
my @runs = (
['core-suite', sub { PAX::CoreSuite->new(manifest_path => "$self->{root}/t/perl_core_suite.json")->run }],
['corpus', sub { PAX::Corpus->new(manifest_path => "$self->{root}/t/corpus.json")->run }],
['cpan-matrix', sub { PAX::CPANMatrix->new(manifest_path => "$self->{root}/t/cpan_matrix.json")->run }],
['bench-matrix', sub { PAX::BenchmarkMatrix->new(manifest_path => "$self->{root}/t/benchmark_matrix.json", iterations => 1, pax_bin => "$self->{root}/bin/pax")->run }],
);
my @failed;
for my $run (@runs) {
my ($name, $code) = @$run;
my $result = eval { $code->() };
if ($@ || !$result || !$result->{passed}) {
push @failed, $@ ? "$name: $@" : $name;
}
}
return {
id => 'sow_validation_matrix',
description => 'Core, nasty Perl, CPAN/XS, and performance validation suites execute successfully',
status => @failed ? 'blocked' : 'passed',
evidence => @failed ? join('; ', @failed) : 'core-suite, corpus, cpan-matrix, bench-matrix',
};
}
sub _check_core_suite {
my ($self) = @_;
my $content = _slurp("$self->{root}/lib/PAX/CLI.pm");
my $report = "$self->{root}/projects/sow-01-project-pax/epic-06-validation-benchmarking-delivery/perl-core-suite-report.md";
return {
id => 'perl_core_suite',
description => 'Perl core regression suite is wired and recorded',
status => ($content =~ /core-suite/ && -f $report) ? 'passed' : 'blocked',
evidence => 'PAX::CoreSuite t/perl_core_suite.json',
};
}
sub _check_cpan_matrix {
my ($self) = @_;
my $content = _slurp("$self->{root}/lib/PAX/CLI.pm");
my $report = "$self->{root}/projects/sow-01-project-pax/epic-06-validation-benchmarking-delivery/cpan-matrix-report.md";
return {
( run in 0.667 second using v1.01-cache-2.11-cpan-71847e10f99 )