versao compilada
tests / ci (push) Canceled after 0s

This commit is contained in:
2026-10-15 17:37:00 +02:00
parent 9a96ee8dfe
commit c13f250b87
935 changed files with 210656 additions and 272 deletions
@@ -5,6 +5,7 @@ namespace App\Http\Controllers;
use App\Models\ExistingBusiness;
use App\Models\ExistingBusinessObject;
use App\Models\Sector;
use App\Policies\ExistingBusinessPolicy;
use App\Services\BusinessFormSchema;
use App\Services\CountryCatalogue;
use App\Services\ExistingBusinessDrafts;
@@ -35,6 +36,7 @@ class ExistingBusinessController extends Controller
$query->where('owner_user_id', '<>', $request->user()->id)->whereIn('status', [
'submitted', 'triage', 'in_review', 'needs_information', 'approval_l1', 'approval_l2', 'approved',
]);
app(ExistingBusinessPolicy::class)->scopeReviewQueue($query, $request->user());
} else {
$query->where('owner_user_id', $request->user()->id);
}
@@ -15,6 +15,7 @@ use App\Services\VerifiedDocumentBinary;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
@@ -55,8 +56,17 @@ class LandAssistanceController extends Controller
public function create(Request $request): Response
{
$context = $request->validate(['context' => ['nullable', 'uuid']])['context'] ?? null;
$dossier = null;
if ($context !== null) {
$case = app(\App\Services\VirtualDesk::class)->case($request->user(), $context);
abort_unless(config('investor-path.enabled') && (int) $case->user_id === $request->user()->id && ! $case->closed_at && $case->journey_id
&& DB::table('investor_journeys')->where('id', $case->journey_id)->whereNotNull('path_definition_id')->whereNull('deleted_at')->exists(), 403);
$dossier = ['id' => $case->id, 'title' => $case->title, 'url' => '/investimentos/'.$case->id];
}
return Inertia::render('land-assistance/form', [
'case' => null,
'returnDossier' => $dossier,
'user' => ['name' => $request->user()->name, 'email' => $request->user()->email],
'disclaimer' => self::DISCLAIMER,
'modelVersion' => 'land-assistance-v1',
@@ -71,6 +81,7 @@ class LandAssistanceController extends Controller
return Inertia::render('land-assistance/form', [
'case' => $case->only(['id', 'reference', 'version', 'status', 'payload']),
'returnDossier' => $this->dossierContext($case),
'user' => ['name' => $request->user()->name, 'email' => $request->user()->email],
'disclaimer' => self::DISCLAIMER,
'modelVersion' => 'land-assistance-v1',
@@ -152,8 +163,11 @@ class LandAssistanceController extends Controller
$submittedPayload = $request->payload();
$case = DB::transaction(function () use ($request, $id, $data, $submission, $submittedPayload): LandAssistanceCase {
$case = $this->owned($request, $id, true);
abort_unless(in_array($case->status, ['draft', 'waiting_applicant'], true), 409, 'Este pedido já não pode ser submetido neste estado.');
$this->checkVersion($case, (int) $data['version']);
$replaying = $case->status === 'support_requested';
abort_unless(in_array($case->status, ['draft', 'waiting_applicant', 'support_requested'], true), 409, 'Este pedido já não pode ser submetido neste estado.');
if (! $replaying) {
$this->checkVersion($case, (int) $data['version']);
}
$payload = [...$case->payload, ...$submittedPayload];
$payload['full_name'] = $payload['full_name'] ?? $request->user()->name;
if (! array_key_exists('email', $payload)) {
@@ -161,6 +175,14 @@ class LandAssistanceController extends Controller
}
$payload['email'] = is_string($payload['email']) && trim($payload['email']) !== '' ? strtolower(trim($payload['email'])) : null;
abort_if(empty($payload['email']) && empty($payload['phone']), 422, 'Indique pelo menos um contacto valido.');
if ($replaying) {
// A retry of the same accepted attempt recovers its original receipt.
// Changed data, another version or a missing receipt must not reopen the case.
abort_unless((int) $case->version === (int) $data['version'] + 1 && $case->interest_request_id
&& hash_equals(hash('sha256', json_encode(Arr::sortRecursive($case->payload), JSON_THROW_ON_ERROR)),
hash('sha256', json_encode(Arr::sortRecursive($payload), JSON_THROW_ON_ERROR))),
409, 'O pedido mudou; recupere o estado atual antes de voltar a enviar.');
}
$message = trim(($payload['request_description'] ?? 'Pedido de apoio sobre Terra e DUAT.')."\nReferência interna: {$case->reference}. Tipo: ".($payload['support_kind'] ?? 'não indicado').'.');
$interest = $submission->receive([
'kind' => 'support', 'fullName' => $payload['full_name'], 'email' => $payload['email'],
@@ -172,13 +194,25 @@ class LandAssistanceController extends Controller
], $case->crm_submission_key, fn () => InterestRequest::create([
'reference' => 'AP-'.now()->year.'-'.Str::ulid(), 'full_name' => $payload['full_name'],
'email' => $payload['email'], 'phone' => $payload['phone'] ?? null,
'country' => $payload['country'] ?? 'Não indicado', 'investor_type' => 'individual',
'country' => $payload['country'] ?? 'Não indicado',
// Use the existing intake vocabulary; retain the more specific declared category.
// This factory only runs for a new receipt. Older submissions/replay hashes stay intact.
'investor_type' => match ($payload['applicant_category'] ?? null) {
'individual' => 'individual', 'entity' => 'empresa', default => 'outro',
},
'sector_interest' => 'Terra e DUAT', 'message' => mb_substr($message, 0, 2000),
'privacy_consent' => true, 'consented_at' => now(), 'status' => 'received', 'source_page' => '/terra-duat',
'metadata' => ['kind' => 'support', 'portal_user_id' => $request->user()->id,
'land_case_id' => $case->id, 'land_case_reference' => $case->reference,
'applicant_category' => $payload['applicant_category'] ?? null,
'declared_origin_country_code' => $payload['declared_origin_country_code'] ?? null],
]));
if ($replaying) {
abort_unless((int) $interest->getKey() === (int) $case->interest_request_id && ! $interest->trashed(),
409, 'O recibo original não está disponível; recupere o estado do pedido.');
return $case;
}
$case->forceFill([
'payload' => $payload,
'status' => 'support_requested',
@@ -287,7 +321,13 @@ class LandAssistanceController extends Controller
public function download(Request $request, string $id, string $attachment): \Illuminate\Http\Response|BinaryFileResponse
{
$case = $this->owned($request, $id);
// Management uses its existing explicit permission; the owner URL stays owner-only.
if ($request->routeIs('land-assistance.manage.download')) {
abort_unless($request->user()->can('manage-portal'), 403);
$case = LandAssistanceCase::whereKey($id)->firstOrFail();
} else {
$case = $this->owned($request, $id);
}
$document = DB::table('land_assistance_documents as link')->join('documents as document', 'document.id', '=', 'link.document_id')
->where('link.case_id', $id)->where('link.id', $attachment)->where('document.status', 'active')->whereNull('document.deleted_at')
->where('document.malware_scan_status', 'clean')->whereColumn('document.malware_scanned_sha256', 'document.sha256')
@@ -327,7 +367,18 @@ class LandAssistanceController extends Controller
}
return ['countryName' => $country['code'] !== null ? $country['name'] : ($payload['country'] ?? 'Não informado'),
'declaredOrigin' => $countries->describe($payload['declared_origin_country_code'] ?? null), 'territoryPaths' => $paths];
'declaredOrigin' => $countries->describe($payload['declared_origin_country_code'] ?? null), 'territoryPaths' => $paths, 'returnDossier' => $this->dossierContext($case)];
}
private function dossierContext(LandAssistanceCase $case): ?array
{
$id = $case->payload['investor_path_case_id'] ?? null;
$actor = request()->user();
if (! $actor || (int) $case->user_id !== $actor->id || ! is_string($id) || ! Str::isUuid($id) || ! config('investor-path.enabled')) {
return null;
}
$dossier = DB::table('desk_cases')->where('id', $id)->where('user_id', $actor->id)->first();
return $dossier ? ['id' => $dossier->id, 'title' => $dossier->title, 'url' => '/investimentos/'.$dossier->id] : null;
}
public function manage(Request $request): Response
@@ -126,6 +126,8 @@ class OpportunityManagementController extends Controller
Inertia::share(['basePath' => str_starts_with($request->path(), 'minhas-oportunidades') ? '/minhas-oportunidades' : '/management/opportunities',
'canonicalOptions' => ($record?->owner_user_id !== null || str_starts_with($request->path(), 'minhas-oportunidades')) ? app(OpportunityCanonicalContract::class)->options($request->user(), $record) : null,
'workflowState' => $record ? $access->state($record) : null,
'profileReauthenticationRequired' => $record && $record->owner_user_id !== null
? app(OpportunityProfileWorkflow::class)->reauthenticationRequired($request->user(), $record) : false,
'publicationState' => $record?->publicationPresentation(),
'canonicalResponse' => $record?->owner_user_id !== null ? app(OpportunityCanonicalResponse::class)->read($request->user(), $record) : null,
'canEditDraft' => $record ? $access->canEdit($request->user(), $record) : false,
@@ -66,7 +66,8 @@ class PortalManagementController extends Controller
'id', 'reference', 'full_name', 'email', 'country', 'metadata', 'sector_interest', 'existing_business_id', 'modality', 'status', 'assigned_to', 'next_action', 'next_action_due_at', 'created_at',
]);
if ($country = $filters['country'] ?? null) {
$query->where('country', $country);
$values = app(CountryCatalogue::class)->filterValues($country);
$query->whereIn(DB::raw('LOWER(BTRIM(country))'), $values);
}
if ($origin = $filters['origin'] ?? null) {
if ($origin === 'unknown') {
@@ -2,6 +2,7 @@
namespace App\Http\Middleware;
use App\Models\ExistingBusiness;
use App\Services\InvestorPath;
use App\Services\LegacyContent;
use App\Services\OpportunityManagement;
@@ -56,6 +57,8 @@ class HandleInertiaRequests extends Middleware
'educationEnabled' => (bool) config('education.enabled', false),
'aiEnabled' => (bool) config('investmoz_ai.enabled', false),
'existingBusinessEnabled' => (bool) config('existing-business.enabled', false),
'businessReviewUrl' => config('existing-business.enabled') && $request->user()?->can('reviewQueue', ExistingBusiness::class)
? '/management/negocios' : null,
'investorPathEnabled' => app(InvestorPath::class)->available(),
'opportunityManagement' => config('portal.opportunity_dashboard_access_enabled') && $request->user() && app(PortalProfileAccess::class)->legacyWriteAllowed($request->user()) ? [
'installed' => app(OpportunityManagement::class)->installed(),
@@ -29,10 +29,11 @@ class StoreLandAssistanceCaseRequest extends FormRequest
{
return [
'version' => [$this->isMethod('post') && ! $this->routeIs('land-assistance.support') ? 'nullable' : 'required', 'integer', 'min:1'],
'payload' => ['required', 'array:support_kind,request_description,project_reference,applicant_category,full_name,contact_person,email,phone,preferred_contact,country,declared_origin_country_code,nationality,representative_name,representative_role,representation_basis,nuit,constitution_or_residency_note,area_status,parcels,purpose,activity,known_occupants,occupant_description,known_improvements,improvements_description,prior_right_status,prior_right_description,conflict_status,conflict_description,official_process,attachments_to_follow,exploration_plan,consultation,additional_information,truth_declaration,contact_consent'],
'payload' => ['required', 'array:support_kind,request_description,project_reference,investor_path_case_id,applicant_category,full_name,contact_person,email,phone,preferred_contact,country,declared_origin_country_code,nationality,representative_name,representative_role,representation_basis,nuit,constitution_or_residency_note,area_status,parcels,purpose,activity,known_occupants,occupant_description,known_improvements,improvements_description,prior_right_status,prior_right_description,conflict_status,conflict_description,official_process,attachments_to_follow,exploration_plan,consultation,additional_information,truth_declaration,contact_consent'],
'payload.support_kind' => ['nullable', 'in:investment,home,family_exploitation,recognition,regularization,delimitation,change_of_use,transfer,existing_process,conflict_guidance,other'],
'payload.request_description' => ['nullable', 'string', 'max:4000'],
'payload.project_reference' => ['nullable', 'string', 'max:160'],
'payload.investor_path_case_id' => ['nullable', 'uuid'],
'payload.applicant_category' => ['nullable', 'in:individual,entity,community,other'],
'payload.full_name' => ['nullable', 'string', 'max:150'],
'payload.contact_person' => ['nullable', 'string', 'max:200'],
@@ -117,6 +118,23 @@ class StoreLandAssistanceCaseRequest extends FormRequest
{
$validator->after(function (Validator $validator): void {
$payload = $this->input('payload', []);
$context = is_array($payload) ? ($payload['investor_path_case_id'] ?? null) : null;
$previous = $this->route('id') ? \App\Models\LandAssistanceCase::whereKey($this->route('id'))->where('user_id', $this->user()->id)->first() : null;
$bound = $previous?->payload['investor_path_case_id'] ?? null;
if ($context !== null) {
$case = is_string($context) && \Illuminate\Support\Str::isUuid($context)
? \Illuminate\Support\Facades\DB::table('desk_cases')->where('id', $context)->first() : null;
if ((! config('investor-path.enabled') && $bound !== $context) || ! $case || (int) $case->user_id !== $this->user()->id
|| ($case->closed_at && $bound !== $context) || ! $case->journey_id
|| ! \Illuminate\Support\Facades\DB::table('investor_journeys')->where('id', $case->journey_id)->whereNotNull('path_definition_id')->whereNull('deleted_at')->exists()) {
$validator->errors()->add('payload.investor_path_case_id', 'Use um dossier do seu percurso disponível para preparação. O acesso direto a Terra e DUAT continua disponível.');
}
}
if ($this->route('id')) {
if ($bound !== null && $context !== $bound) {
$validator->errors()->add('payload.investor_path_case_id', 'Preserve o vínculo deste pedido ao dossier original.');
}
}
if (is_array($payload) && is_array($payload['parcels'] ?? null)) {
$geography = app(InvestmentGeography::class);
$levels = ['province_id' => 'province', 'district_id' => 'district', 'admin_post_id' => 'admin_post', 'locality_id' => 'locality'];
+11
View File
@@ -29,6 +29,17 @@ class Opportunity extends Model
protected $hidden = ['management_draft', 'management_creation_key', 'management_version', 'first_submitted_at', 'management_closed_once', 'owner_user_id', 'organization_id', 'workflow_context'];
protected $appends = ['maturity_catalogue_version'];
public function getMaturityCatalogueVersionAttribute(): ?string
{
// Only published metadata is public; never expose the current private draft.
$version = data_get($this->workflow_context, 'publication.maturity.catalogue_version');
return in_array($version, [\App\Services\OpportunityMaturity::VERSION, \App\Services\OpportunityMaturity::LEGACY], true)
? $version : null;
}
protected $fillable = [
'sector_id', 'reference', 'title', 'slug', 'summary', 'description',
'province', 'district', 'promoter_name', 'promoter_type',
+55 -10
View File
@@ -4,6 +4,8 @@ namespace App\Policies;
use App\Models\ExistingBusiness;
use App\Models\User;
use App\Services\PortalProfileAccess;
use Illuminate\Database\Eloquent\Builder;
class ExistingBusinessPolicy
{
@@ -24,9 +26,14 @@ class ExistingBusinessPolicy
return true;
}
$reviewedStates = ['rejected', 'published', 'suspended', 'cancelled', 'archived'];
if (app(PortalProfileAccess::class)->available()) {
$reviewedStates[] = 'approved';
}
return ! $business->trashed() && $business->owner_user_id !== $user->id
&& in_array($business->status, ['rejected', 'published', 'suspended', 'cancelled', 'archived'], true)
&& $this->reviewQueue($user);
&& in_array($business->status, $reviewedStates, true)
&& $this->designatedAny($user, $business);
}
public function delete(User $user, ExistingBusiness $business): bool
@@ -43,41 +50,56 @@ class ExistingBusinessPolicy
{
return ! $business->trashed() && $business->owner_user_id !== $user->id
&& in_array($business->status, ['triage', 'in_review', 'needs_information'], true)
&& $this->designated($user, 'reviewers');
&& $this->designated($user, 'reviewers', $business);
}
public function triage(User $user, ExistingBusiness $business): bool
{
return ! $business->trashed() && $business->owner_user_id !== $user->id
&& in_array($business->status, ['submitted', 'triage'], true)
&& $this->designated($user, 'triagers');
&& $this->designated($user, 'triagers', $business);
}
public function approveLevelOne(User $user, ExistingBusiness $business): bool
{
return ! $business->trashed() && $business->owner_user_id !== $user->id
&& $business->status === 'approval_l1'
&& $this->designated($user, 'approvers_l1');
&& $this->designated($user, 'approvers_l1', $business);
}
public function approveLevelTwo(User $user, ExistingBusiness $business): bool
{
return ! $business->trashed() && $business->owner_user_id !== $user->id
&& $business->status === 'approval_l2'
&& $this->designated($user, 'approvers_l2');
&& $this->designated($user, 'approvers_l2', $business);
}
public function publish(User $user, ExistingBusiness $business): bool
{
return ! $business->trashed() && $business->owner_user_id !== $user->id
&& $business->status === 'approved'
&& $this->designated($user, 'publishers');
&& $this->designated($user, 'publishers', $business);
}
public function reviewQueue(User $user): bool
{
return $this->designatedAny($user);
}
/** Filter before projecting or decrypting private fields in the review queue. */
public function scopeReviewQueue(Builder $query, User $user): void
{
if (app(PortalProfileAccess::class)->available()) {
$query->where('modality', 'company_sale');
$ids = (clone $query)->get()->filter(fn (ExistingBusiness $business) => $this->view($user, $business))->modelKeys();
$query->whereKey($ids);
}
}
private function designatedAny(User $user, ?ExistingBusiness $business = null): bool
{
foreach (['reviewers', 'triagers', 'approvers_l1', 'approvers_l2', 'publishers'] as $designation) {
if ($this->designated($user, $designation)) {
if ($this->designated($user, $designation, $business)) {
return true;
}
}
@@ -85,9 +107,32 @@ class ExistingBusinessPolicy
return false;
}
private function designated(User $user, string $designation): bool
private function designated(User $user, string $designation, ?ExistingBusiness $business = null): bool
{
return $user->hasVerifiedEmail() && $user->can('manage-portal')
$access = app(PortalProfileAccess::class);
if ($access->available()) {
// Only the existing company-sale consumer is reconciled in this increment.
// Do not translate other modalities or invent an organization from free text.
if (($business !== null && $business->modality !== 'company_sale') || ! $access->mfa($user)) {
return false;
}
$role = $designation === 'publishers' ? 'publisher' : 'validator';
if (! $access->operational($user, $role === 'publisher' ? 'publish' : 'validate')) {
return false;
}
foreach ($access->grants($user, $role) as $grant) {
if ($grant->organization_id === null
&& in_array('business_sale', json_decode($grant->opportunity_types, true, 512, JSON_THROW_ON_ERROR), true)) {
return true;
}
}
return false;
}
// Legacy-only environments retain their explicit lists; a revoked/scoped v1
// assignment must never regain wider permissions through that allowlist.
return $user->hasVerifiedEmail() && $access->legacyWriteAllowed($user)
&& (bool) $user->two_factor_confirmed_at && (bool) $user->two_factor_secret
&& in_array(strtolower($user->email), config('existing-business.'.$designation, []), true);
}
+25
View File
@@ -46,6 +46,31 @@ final class CountryCatalogue
};
}
/**
* Exact catalogue labels for reading legacy free-text country values.
* Does not infer request origin, alter stored values or classify unmatched text.
* Only labels belonging to one ISO country are included.
*
* @return list<string> Case-folded country code and catalogue labels.
*/
public function filterValues(string $code): array
{
$countries = $this->all();
$owners = [];
$selected = [];
foreach ($countries as $country) {
foreach (array_unique([$country['code'], $country['name'], $country['name_en']]) as $label) {
$key = mb_strtolower(trim($label), 'UTF-8');
$owners[$key][$country['code']] = true;
if ($country['code'] === $code) {
$selected[$key] = true;
}
}
}
return array_values(array_filter(array_keys($selected), fn ($key) => count($owners[$key]) === 1));
}
/** @return array{code:string|null,name:string} */
public function describe(?string $code): array
{
+4 -2
View File
@@ -37,6 +37,7 @@ final class ExistingBusinessIntake
return DB::transaction(function () use ($actor, $id, $version, $action, $note, $consent, $confirmationCode) {
$business = app(BusinessRepository::class)->find($id, true);
$profileWorkflow = $business->modality === 'company_sale' && app(PortalProfileAccess::class)->available();
$ability = match ($action) {
OpportunityStatus::Submitted->value, OpportunityStatus::Withdrawn->value => 'owns',
OpportunityStatus::Triage->value => 'triage',
@@ -117,7 +118,7 @@ final class ExistingBusinessIntake
if ($action === OpportunityStatus::Approved->value) {
$levelOneActor = DB::table('business_workflow_transitions')->where('existing_business_id', $business->id)
->where('to_status', OpportunityStatus::ApprovalL2->value)->orderByDesc('created_at')->value('actor_id');
abort_unless($levelOneActor !== null && (int) $levelOneActor !== (int) $actor->id, 403,
abort_unless($levelOneActor !== null && ($profileWorkflow || (int) $levelOneActor !== (int) $actor->id), 403,
'A aprovação de nível 2 deve ser feita por uma pessoa diferente da aprovação de nível 1.');
}
if ($action === OpportunityStatus::Published->value) {
@@ -146,7 +147,8 @@ final class ExistingBusinessIntake
'actor_id' => $actor->id,
'reason' => Crypt::encryptString($note),
'correlation_id' => $correlationId,
'metadata' => json_encode(['version_no' => $business->version_no, 'source' => 'portal-intake'], JSON_THROW_ON_ERROR),
'metadata' => json_encode(['version_no' => $business->version_no, 'source' => 'portal-intake',
'authorization_mode' => $profileWorkflow ? 'profiles-v1-company-sale' : 'legacy-designations'], JSON_THROW_ON_ERROR),
'created_at' => now(),
]);
if ($action === OpportunityStatus::Submitted->value) {
+4 -2
View File
@@ -26,7 +26,7 @@ class InvestmentCatalogue
'geo_location_id' => ['nullable', 'uuid'], 'education' => ['nullable', 'boolean'],
'zee_id' => ['nullable', 'uuid'], 'zfi_id' => ['nullable', 'uuid'], 'park_id' => ['nullable', 'uuid'],
'dimension' => ['nullable', 'in:cluster,corridor,zee,zfi'], 'view' => ['nullable', 'in:grid,list,map,combined'],
'maturity_level' => ['nullable', 'integer', 'between:1,6'], 'facets' => ['nullable', 'array', 'max:20'], 'facets.*' => ['integer', 'min:1'],
'maturity_level' => ['nullable', 'integer', 'between:1,8'], 'facets' => ['nullable', 'array', 'max:20'], 'facets.*' => ['integer', 'min:1'],
'min_amount' => ['nullable', 'numeric', 'min:0', 'max:999999999999'],
'max_amount' => ['nullable', 'numeric', 'min:0', 'max:999999999999', ...($request->filled('min_amount') ? ['gte:min_amount'] : [])],
'currency' => ['nullable', 'required_with:min_amount,max_amount', 'in:MZN,USD,EUR,ZAR'],
@@ -179,7 +179,9 @@ class InvestmentCatalogue
public function references(bool $management = false, array $territoryFilters = []): array
{
$result = ['options' => DB::table('investment_reference_options')->when(! $management, fn ($q) => $q->where('active', true))->orderBy('sort_order')->orderBy('label')->get(),
'sectors' => DB::table('sectors')->where('is_active', true)->whereNull('deleted_at')->orderBy('name')->get(['id', 'name', 'slug'])];
'sectors' => DB::table('sectors')->where('is_active', true)->whereNull('deleted_at')->orderBy('name')->get(['id', 'name', 'slug']),
'maturityCatalogue' => ['version'=>OpportunityMaturity::VERSION, 'stages'=>OpportunityMaturity::STAGES,
'legacyVersion'=>OpportunityMaturity::LEGACY, 'legacyLabels'=>OpportunityMaturity::LEGACY_LABELS]];
foreach (self::RELATIONS as $relation => [$foreign, $table]) {
$query = DB::table($table)->whereNull('deleted_at');
if (! $management) {
+7 -1
View File
@@ -117,8 +117,14 @@ class InvestmentRelations
/** @return array<string,mixed> */
public function dossier(InvestmentDossier $dossier, bool $management = false): array
{
$sourceEvidence = [];
if ($dossier->project_id) {
$sourceEvidence = app(InvestmentTerritorialTraceability::class)->sources('projects', $dossier->project_id);
} elseif ($dossier->cluster_id) {
$sourceEvidence = app(InvestmentTerritorialTraceability::class)->sources('economic_clusters', $dossier->cluster_id);
}
$result = ['locations' => [], 'members' => [], 'clusters' => [], 'chainLinks' => [], 'chains' => [],
'source_evidence' => app(InvestmentTerritorialTraceability::class)->sources($dossier->project_id ? 'projects' : 'economic_clusters', $dossier->project_id ?? $dossier->cluster_id ?? '')];
'source_evidence' => $sourceEvidence];
if ($dossier->project_id) {
$result['locations'] = $this->projectLocations($dossier->project_id, $management);
$memberships = $this->memberships()->where('cp.project_id', $dossier->project_id)->get(['cp.cluster_id', 'cp.role', 'cp.validation_status', 'cp.source_reference']);
+6 -1
View File
@@ -125,6 +125,10 @@ final class InvestorPath
$results = (int) $case->user_id === $actor->id ? ($path['results'] ?? []) : [];
$next = collect($steps)->first(fn ($step) => $step['preparation_allowed'] && ! in_array($step['state'], ['completed', 'approved', 'waiting_external', 'submitted', 'reviewing'], true));
$landCase = (int) $case->user_id === $actor->id
? \App\Models\LandAssistanceCase::where('user_id', $actor->id)->latest('updated_at')->get()
->first(fn ($land) => ($land->payload['investor_path_case_id'] ?? null) === $id) : null;
return ['case' => ['id' => $id, 'title' => $case->title, 'version' => $case->version, 'closed' => $case->closed_at !== null],
'journey_id' => $journey->id, 'definition_id' => $version->id, 'definition_version' => $version->version_no, 'source_sha256' => $definition['source_sha256'],
'phases' => $definition['phases'], 'steps' => $steps, 'facts' => $facts, 'fact_reasons' => $path['fact_reasons'] ?? [],
@@ -140,7 +144,8 @@ final class InvestorPath
->unique('code')->values()->map(fn ($s) => ['id' => $s->id, 'title' => json_decode($s->definition, true)['title']]),
'tools' => ['simulator' => (int) $case->user_id === $actor->id ? '/simulador-fiscal?context='.$id.($case->simulation_id ? '&draft='.$case->simulation_id : '') : null,
'desk' => '/balcao-virtual/dossiers/'.$id, 'guidance' => '/balcao-virtual/dossiers/'.$id.'/orientacao',
'library' => '/documentos?context='.$id, 'opportunities' => '/oportunidades?context='.$id, 'territory' => '/zonas?context='.$id, 'partners' => '/parcerias/painel?context='.$id]];
'library' => '/documentos?context='.$id, 'opportunities' => '/oportunidades?context='.$id, 'territory' => '/zonas?context='.$id, 'partners' => '/parcerias/painel?context='.$id,
'land' => (int) $case->user_id === $actor->id ? ($landCase ? '/investidor/terra-duat/'.$landCase->id : '/investidor/terra-duat/novo?context='.$id) : null]];
}
/** @param array<string,mixed> $input */
+65 -15
View File
@@ -148,24 +148,64 @@ class OpportunityCanonicalContract
$data = $this->schemaData($payload, $schema['$defs']['opportunityCreate'], $schema['$defs']);
$result = $validator->validate($data, json_decode(json_encode($schema, JSON_THROW_ON_ERROR)));
if ($error = $result->error()) {
$errors = [];
foreach ((new ErrorFormatter)->format($error) as $path => $messages) {
$errors['canonical'.str_replace('/', '.', $path)] = $messages;
throw ValidationException::withMessages($this->schemaValidationErrors($error));
}
}
/** @return array<string,list<string>> */
private function schemaValidationErrors(ValidationError $error): array
{
$errors = [];
$formatter = new ErrorFormatter;
$collect = function (ValidationError $node) use (&$collect, &$errors, $formatter): void {
if ($node->subErrors() !== []) {
foreach ($node->subErrors() as $child) {
$collect($child);
}
return;
}
$required = function (ValidationError $node) use (&$required, &$errors): void {
if ($node->keyword() === 'required') {
$prefix = 'canonical.'.implode('.', $node->data()->fullPath());
foreach ($node->args()['missing'] ?? [] as $field) {
$errors[rtrim($prefix, '.').'.'.$field] = ['Preencha este campo antes de submeter.'];
$prefix = rtrim('canonical.'.implode('.', $node->data()->fullPath()), '.');
$args = $node->args();
if ($node->keyword() === 'required') {
foreach ($args['missing'] ?? [] as $field) {
$errors[$prefix.'.'.$field][] = 'Preencha este campo antes de submeter.';
}
return;
}
if ($node->keyword() === 'additionalProperties') {
$definition = $node->schema()->info()->data();
$declared = is_object($definition) ? (array) ($definition->properties ?? []) : [];
foreach ($args['properties'] ?? [] as $field) {
// Opis can report declared properties as unchecked after a sibling field fails.
// Keep real unknown-property errors without turning valid fields into errors.
if (! array_key_exists($field, $declared)) {
$errors[$prefix.'.'.$field][] = 'Campo não previsto no contrato desta categoria.';
}
}
foreach ($node->subErrors() as $child) {
$required($child);
}
};
$required($error);
throw ValidationException::withMessages($errors);
}
return;
}
if ($node->keyword() === 'minLength') {
$errors[$prefix][] = 'Preencha este campo com pelo menos '.$args['min'].' caracteres; tem '.$args['length'].'.';
return;
}
if ($node->keyword() === 'maxLength') {
$errors[$prefix][] = 'Este campo admite até '.$args['max'].' caracteres; tem '.$args['length'].'.';
return;
}
foreach ($formatter->format($node) as $path => $messages) {
$key = rtrim('canonical'.str_replace('/', '.', $path), '.');
$errors[$key] = array_values(array_unique([...($errors[$key] ?? []), ...$messages]));
}
};
$collect($error);
// Formatting must never make an invalid schema result acceptable.
return $errors ?: ['canonical' => ['Não foi possível validar o contrato. Reveja os campos preenchidos.']];
}
/** @param array<string,mixed> $node
@@ -246,6 +286,13 @@ class OpportunityCanonicalContract
}
} else {
$location = $row->payload;
// §10.2 area/unit consistency applies at submission. Resource drafts may
// retain incomplete measurements; never invent a unit or convert values.
$hasArea = isset($location['area_value']);
$hasUnit = isset($location['area_unit']) && $location['area_unit'] !== '';
$check(! $hasArea || $hasUnit, "locations.$index.area_unit", 'Indique a unidade da área antes de submeter; a preparação incompleta continua guardada nos recursos.');
$check(! $hasUnit || $hasArea, "locations.$index.area_value", 'Indique o valor da área antes de submeter; a unidade não determina o valor.');
$check(! $hasUnit || in_array($location['area_unit'], OpportunityResources::AREA_UNITS, true), "locations.$index.area_unit", 'Use uma unidade do catálogo existente: sqm, ha ou sqkm.');
$check(! empty($location['district_id']) && ! empty($location['role']) && array_key_exists('is_primary', $location), "locations.$index", 'Localização requer distrito, papel e indicação de principal.');
app(InvestmentGeography::class)->selection($location, true);
$country = $location['country_code'] ?? null;
@@ -492,10 +539,13 @@ class OpportunityCanonicalContract
->orWhereExists(fn ($i) => $i->selectRaw('1')->from('investor_contacts as ic')->join('investors as inv', 'inv.id', '=', 'ic.investor_id')->whereColumn('ic.contact_id', 'contacts.id')->whereIn('inv.organization_id', $orgs)->whereNull('inv.deleted_at'));
})->get(['id', 'full_name']);
$submissionProperties = $this->schema(false)['$defs']['opportunityCreate']['properties'];
return ['version' => self::VERSION, 'modularProfiles' => app(OpportunityModularProfiles::class)->enabled() ? OpportunityModularProfiles::PROFILES : [],
'historyVersion' => app(OpportunityModularProfiles::class)->enabled() ? OpportunityModularProfiles::HISTORY_VERSION : null,
'schema' => $this->schema(true)['$defs']['opportunityCreate'],
'definitions' => $this->schema(true)['$defs'],
'submissionTextLimits' => ['demand_statement' => array_intersect_key($submissionProperties['demand_statement'], array_flip(['minLength', 'maxLength']))],
'activities' => DB::table('economic_activities')->where('status', 'published')->get(['id', 'parent_id', 'sector_id', 'label_pt_mz', 'catalog_version_id']),
'contacts' => $contacts, 'contactInvestors' => $record?->organization_id ? DB::table('investors')->where('organization_id', $record->organization_id)->whereNull('deleted_at')->whereIn('status', ['prospect', 'active'])->get(['id', 'legal_name']) : [],
'countries' => app(CountryCatalogue::class)->all(),
@@ -82,6 +82,9 @@ class OpportunityCategoryFields
$lr['community_consultation'] = $this->object(['status' => $s, 'minutes_document_id' => $d, 'participants' => $strings, 'map_document_id' => $d, 'commitments' => $s, 'date' => $date], ['status', 'minutes_document_id', 'participants', 'map_document_id', 'commitments', 'date']);
$lr['consideration'] = $this->object(['object' => ['enum' => ['improvements', 'assets', 'operation', 'partnership']], 'amount' => $n, 'currency' => ['type' => 'string', 'pattern' => '^[A-Z]{3}$']], ['object', 'amount', 'currency']);
$lr += ['holder_document_id' => $d, 'communities_affected' => $bool, 'exploitation_plan_required' => $bool];
// Explicit optional unit of the parcel's existing area. Older versions stay unknown;
// do not assign the location's unit or convert the recorded numeric area.
$defs['parcelCreate']['properties']['area_unit'] = ['enum' => [...OpportunityResources::AREA_UNITS, null]];
$defs['landRightsCreate']['required'] = [...$defs['landRightsCreate']['required'], 'holder_document_id', 'communities_affected', 'exploitation_plan_required'];
$bt = &$defs['businessTransactionCreate']['properties'];
$bt['valuation'] = $valuation;
+8 -2
View File
@@ -20,6 +20,14 @@ class OpportunityContacts
$record = Opportunity::withTrashed()->findOrFail($id);
$access->authorize($actor, 'edit', $record);
abort_unless($access->mfa($actor), 403, 'Confirme a autenticação multifator nesta sessão.');
// Validate the persisted form of names/email, rather than padding.
// Non-string input stays with the validator and cannot cause a TypeError.
if (is_string($input['full_name'] ?? null)) {
$input['full_name'] = trim(preg_replace('/\s+/u', ' ', $input['full_name']));
}
if (is_string($input['email'] ?? null)) {
$input['email'] = strtolower(trim($input['email']));
}
$data = Validator::make($input, [
'etag' => 'required|string|size:64',
'full_name' => 'required|string|min:2|max:150',
@@ -28,8 +36,6 @@ class OpportunityContacts
'investor_id' => 'nullable|uuid',
'investor_type' => ['nullable', Rule::in(['domestic', 'foreign', 'institutional', 'individual'])],
])->validate();
$data['email'] = strtolower(trim($data['email']));
$data['full_name'] = trim(preg_replace('/\s+/u', ' ', $data['full_name']));
return DB::transaction(function () use ($actor, $id, $data, $access) {
$record = Opportunity::withTrashed()->whereKey($id)->lockForUpdate()->firstOrFail();
+31 -5
View File
@@ -11,6 +11,8 @@ use Illuminate\Validation\ValidationException;
class OpportunityProfileWorkflow
{
private const PROMOTER_ACTIONS = ['submit', 'request_archive', 'appeal', 'request_revision'];
public function __construct(private PortalProfileAccess $access, private OpportunityManagement $management,
private OpportunityCanonicalContract $contract, private OpportunityWorkflowTasks $tasks) {}
@@ -38,7 +40,9 @@ class OpportunityProfileWorkflow
$actions[] = 'appeal';
}
}
if ($this->access->mfa($actor) && ! $this->access->conflict($actor, $record)) {
// List scoped capabilities; the page disables execution until MFA is fresh.
// authorizeAction still verifies MFA for every review/publication request.
if (! $this->access->conflict($actor, $record)) {
if ($this->access->scoped($actor, 'validator', $record->organization_id, $record->opportunity_category) && $this->access->operational($actor, 'validate', $record->id)) {
if ($state === 'approved' && count(array_filter($record->workflow_context['conditions'] ?? [], fn ($condition) => $condition['status'] === 'open' && $condition['blocking_action'] === 'publish')) > 0) {
$actions[] = 'review_gate';
@@ -90,6 +94,12 @@ class OpportunityProfileWorkflow
return $actions;
}
public function reauthenticationRequired(User $actor, Opportunity $record): bool
{
return ! $this->access->mfa($actor)
&& array_diff($this->actions($actor, $record), self::PROMOTER_ACTIONS) !== [];
}
/** Scoped names/IDs only; no secrets or implicit assignees.
* @return array<string,mixed> */
public function participants(User $actor, Opportunity $record): array
@@ -317,7 +327,9 @@ class OpportunityProfileWorkflow
abort_unless(in_array($p['business_transaction']['due_diligence_status'], ['data_room_ready', 'in_progress', 'completed', 'exceptions'], true), 422, 'Data room mínimo não preparado.');
}
if (isset($context['publication'])) {
$context['publication_history'][] = $context['publication'];
$context['publication_history'][] = [...$context['publication'],
'public_maturity_before_republication' => ['level' => $record->maturity_level, 'label' => $record->maturity_label,
'catalogue_version' => $context['publication']['maturity']['catalogue_version'] ?? null]];
}
$context['publication'] = [...$decision, 'hash' => $snapshot['hash'], 'visibility' => $p['visibility'],
'public_fields' => ['title', 'summary', 'description', 'sector_id', 'province', 'district']];
@@ -327,6 +339,16 @@ class OpportunityProfileWorkflow
$record->summary = $projection['summary'];
$record->description = $projection['description'];
$record->sector_id = $p['sector_id'];
if (! empty($p['maturity_stage'])) {
// Project only the explicitly selected, approved V2 stage.
// Existing legacy positions/labels are retained in publication history.
$maturity = app(OpportunityMaturity::class)->normalize(['maturity_stage' => $p['maturity_stage'],
'maturity_catalogue_version' => OpportunityMaturity::VERSION]);
$record->maturity_level = $maturity['maturity_level'];
$record->maturity_label = $maturity['maturity_label'];
$context['publication']['maturity'] = ['catalogue_version' => $maturity['maturity_catalogue_version'],
'stage' => $maturity['maturity_stage'], 'level' => $maturity['maturity_level'], 'label' => $maturity['maturity_label']];
}
$locations = array_values(array_filter($snapshot['resources']['locations'], fn ($location) => $location['payload']['is_primary'] ?? false));
$location = $locations[0]; // The contract requires exactly one primary location.
$path = app(InvestmentGeography::class)->selection($location['payload'], true);
@@ -475,13 +497,17 @@ class OpportunityProfileWorkflow
$this->access->authorize($actor, 'view', $record);
$promoter = $this->access->promoterRecordScope($actor, $record)
&& ($record->organization_id !== null || (int) $record->owner_user_id === $actor->id);
if (in_array($action, ['submit', 'request_archive', 'appeal', 'request_revision'], true)) {
if (in_array($action, self::PROMOTER_ACTIONS, true)) {
abort_unless($promoter && $this->access->operational($actor, 'edit', $record->id), 403);
} else {
$role = in_array($action, ['publish', 'assign_publication', 'suspend', 'archive'], true) ? 'publisher' : 'validator';
$operation = $role === 'publisher' ? (in_array($action, ['publish', 'assign_publication'], true) ? 'publish' : 'archive') : 'validate';
abort_unless($this->access->scoped($actor, $role, $record->organization_id, $record->opportunity_category)
&& $this->access->mfa($actor) && $this->access->operational($actor, $operation, $record->id) && ! $this->access->conflict($actor, $record), 403, 'Papel, MFA e independência necessários.');
$eligible = $this->access->scoped($actor, $role, $record->organization_id, $record->opportunity_category)
&& $this->access->operational($actor, $operation, $record->id) && ! $this->access->conflict($actor, $record);
if ($eligible && ! $this->access->mfa($actor)) {
abort(403, 'A confirmação MFA desta janela precisa de renovação. Entre novamente nesta janela com o seu autenticador; os dados já guardados foram preservados.', ['X-Portal-Reauthentication' => 'required']);
}
abort_unless($eligible && $this->access->mfa($actor), 403, 'Papel, MFA e independência necessários.');
if ($action === 'publish') {
abort_if((int) ($record->workflow_context['approval']['actor_id'] ?? 0) === $actor->id, 403, 'O aprovador não publica a mesma versão.');
abort_if(isset($record->workflow_context['publication_assignment']['assignee_user_id']) && (int) $record->workflow_context['publication_assignment']['assignee_user_id'] !== $actor->id, 403, 'Publicação atribuída a outro Publicador; requer reatribuição explícita.');
+4 -1
View File
@@ -20,6 +20,9 @@ class OpportunityResources
{
public const KINDS = ['documents', 'images', 'locations'];
// Existing §10.2 catalogue; shared with the compatibility editor, no inferred conversions.
public const AREA_UNITS = ['sqm', 'ha', 'sqkm'];
public function installed(): bool
{
return Schema::hasTable('opportunity_images');
@@ -213,7 +216,7 @@ class OpportunityResources
$rules = ['title' => 'nullable|string|max:120', 'source_reference' => 'nullable|string|max:2000', 'source_date' => 'nullable|date_format:Y-m-d', 'visibility' => 'nullable|in:internal,authenticated,public'];
if ($kind === 'locations') {
$rules += ['country_code' => ['nullable', app(CountryCatalogue::class)->rule()]];
$rules += ['province_id' => 'nullable|uuid', 'district_id' => 'nullable|uuid', 'admin_post_id' => 'nullable|uuid', 'locality_id' => 'nullable|uuid', 'role' => 'nullable|in:headquarters,production,raw_material,storage,logistics,market,support,other', 'role_description' => 'nullable|string|max:1000', 'operational_unit' => 'nullable|string|max:120', 'is_primary' => 'nullable|boolean', 'address' => 'nullable|string|max:300', 'geometry' => 'nullable|array', 'area_value' => 'nullable|numeric|gt:0', 'area_unit' => 'nullable|in:sqm,ha,sqkm', 'allocation_percentage' => 'nullable|numeric|between:0,100', 'territorial_purpose' => 'nullable|in:implementation,context,impact,coverage', 'multi_district_rationale' => 'nullable|string|max:1000'];
$rules += ['province_id' => 'nullable|uuid', 'district_id' => 'nullable|uuid', 'admin_post_id' => 'nullable|uuid', 'locality_id' => 'nullable|uuid', 'role' => 'nullable|in:headquarters,production,raw_material,storage,logistics,market,support,other', 'role_description' => 'nullable|string|max:1000', 'operational_unit' => 'nullable|string|max:120', 'is_primary' => 'nullable|boolean', 'address' => 'nullable|string|max:300', 'geometry' => 'nullable|array', 'area_value' => 'nullable|numeric|gt:0', 'area_unit' => ['nullable', Rule::in(self::AREA_UNITS)], 'allocation_percentage' => 'nullable|numeric|between:0,100', 'territorial_purpose' => 'nullable|in:implementation,context,impact,coverage', 'multi_district_rationale' => 'nullable|string|max:1000'];
} elseif ($kind === 'images') {
$rules += ['role' => 'nullable|in:cover,gallery,location,asset,product,plan,rendering,evidence,other', 'role_description' => 'nullable|string|max:1000', 'is_cover' => 'nullable|boolean', 'caption' => 'nullable|string|max:300', 'alt_text' => 'nullable|string|max:250', 'location_id' => ['nullable', 'uuid', Rule::exists('opportunity_location_drafts', 'id')->where('opportunity_id', $opportunityId)->whereNull('deleted_at')], 'captured_at' => 'nullable|date_format:Y-m-d|before_or_equal:today', 'author_source' => 'nullable|string|max:150', 'rights_status' => 'nullable|in:owned,licensed,authorized,public_domain', 'rights_document_id' => ['nullable', 'uuid', Rule::exists('opportunity_documents', 'id')->where('opportunity_id', $opportunityId)->whereNull('deleted_at')], 'rights_valid_until' => 'nullable|date_format:Y-m-d', 'sort_order' => 'nullable|integer|min:0'];
} else {
+15 -5
View File
@@ -7,13 +7,16 @@ use Illuminate\Support\Arr;
/** §28.1: preserve signed decisions; only changed review scopes need new decisions. */
class OpportunityReviewMateriality
{
public const VERSION = 'review-scopes-20261011-v3';
public const VERSION = 'review-scopes-20261012-v4';
// Preserve the projections used by earlier signed reviews.
public const BEFORE_FRANCHISE_FINANCE_VERSION = 'review-scopes-20261011-v3';
public const PREVIOUS_VERSION = 'review-scopes-20261011-v2';
/** @param array<string,mixed> $snapshot
* @return array<string,mixed> */
private function scope(array $snapshot, string $gate, bool $extended = true): array
private function scope(array $snapshot, string $gate, bool $extended = true, bool $franchiseFinance = true): array
{
$p = $snapshot['payload'] ?? [];
$common = ['opportunity_category', 'promoter_id', 'promoter_type', 'sector_id', 'subsector_id', 'economic_activity_id', 'demand_statement', 'executive_summary'];
@@ -49,6 +52,11 @@ class OpportunityReviewMateriality
default => [],
}];
}
if ($franchiseFinance && $gate === 'financial_review' && ($p['opportunity_category'] ?? '') === 'franchise') {
// Existing canonical monetary obligations affect the existing financial review.
// No rates, calculations, reviewers or external decisions are introduced here.
$fields = [...$fields, 'business_transaction.franchise_terms.initial_fee', 'business_transaction.franchise_terms.royalties'];
}
$data = [];
foreach ([...$common, ...$fields] as $field) {
if (! is_string($field)) {
@@ -88,8 +96,10 @@ class OpportunityReviewMateriality
* @param array<string,mixed> $review */
public function hash(array $snapshot, string $gate, array $review = [], bool $legacy = false, ?string $rule = null): string
{
$extended = ! $legacy && ($rule ?? self::VERSION) !== self::PREVIOUS_VERSION;
$data = $this->scope($snapshot, $gate, $extended);
$effectiveRule = $rule ?? self::VERSION;
$extended = ! $legacy && $effectiveRule !== self::PREVIOUS_VERSION;
$franchiseFinance = ! $legacy && ! in_array($effectiveRule, [self::PREVIOUS_VERSION, self::BEFORE_FRANCHISE_FINANCE_VERSION], true);
$data = $this->scope($snapshot, $gate, $extended, $franchiseFinance);
$locationGates = ['registry_urban_review', 'cadastral_screening', 'legal_territorial_review', 'property_review'];
if (! $legacy) {
$locationGates = [...$locationGates, 'land_legal_review', 'community_environment_review', 'competent_authority_clearance'];
@@ -130,7 +140,7 @@ class OpportunityReviewMateriality
return true; // Caller must independently verify the original signed submission hash.
}
$rule = $review['scope_rule'] ?? '';
$legacy = ! in_array($rule, [self::VERSION, self::PREVIOUS_VERSION], true);
$legacy = ! in_array($rule, [self::VERSION, self::PREVIOUS_VERSION, self::BEFORE_FRANCHISE_FINANCE_VERSION], true);
$expected = $this->hash($snapshot, $gate, $review, $legacy, $rule);
return hash_equals($review['scope_hash'], $expected);
@@ -30,7 +30,7 @@ Passwords e QR 2FAS individuais estão apenas nos ficheiros locais privados `sto
**Tentativa QA21 registada:** entrada https://portal-investidor.test:18445/aceitacao-B-396c691930bc.html bloqueada antes do login: IAB `ERR_CERT_AUTHORITY_INVALID`; conector Windows com pipe nativo indisponível (`os error2`). Linha 01 não chegou a abrir o contrato; as 12 linhas/partes permanecem **não observado**, não são 12 falhas do produto. Não foram executadas QA24/25, QA17 ou revogações. Sem resets, bypass TLS, credenciais lidas, dados alterados ou repetição de provas aceites. Evidência: `acceptance-396c-QA21-browser-block-20261014.json`.
Mantêm-se os mesmos 12 trechos. Os números abaixo são posições do roteiro existente, não novos requisitos. Ainda não houve nova execução: cada linha e parte começa como **não observado**. Registar apenas **passou / falhou / não observado**, com URL e evidência.
Mantêm-se os mesmos 12 trechos. Os números abaixo são posições do roteiro existente, não novos requisitos. Atualização manual de 15/10/2026: **linha 01/fase 1/QA21 passou** (campos da licença e documento aberto e legível), **linha 03/QA21 passou** (os cinco pontos de consulta do Negócio 33) e **linha 04 passou** (mapa público e corredor da carteira). A fase 2 da linha 01 e as restantes partes conservam os estados anteriores; a linha 01 composta continua pendente. Registar apenas **passou / falhou / não observado**, com URL e evidência. O bloqueio automático de 14/10 acima permanece como histórico da tentativa, sem invalidar estas provas manuais.
1. **QA21:** campos, documentos, países, mapas, preparação/submissão quando necessária e recuperação dos vínculos. Consulta pública numa janela sem sessão.
2. **QA24/QA25:** revisões e transições restantes dos casos 30/34/56 e do anúncio antigo, na sequência aplicável. QA24 solicita correção; QA21 corrige/ressubmete na sessão mantida; QA24 revê/aprova; QA25 publica. Aproveitar estas sessões para a recusa de QA24 e o acesso de QA25 no Balcão. Não repetir transições já cobertas.
@@ -41,18 +41,18 @@ Manter QA21 em sessão/perfil de navegador separado para o único retorno exigid
| Linha existente | Percurso/caso | Fases | Ação restante original e acesso QA | Resultado |
| --- | --- | --- | --- | --- |
| 01 | Projeto30 — licença e materialidade | 1 → 2 | [Abrir](https://portal-investidor.test:18445/minhas-oportunidades/30/edit) — Conferir a licença específica do projeto 30, abrir a peça em Recursos e observar o resultado da alteração de licenciamento: revisão legal afetada e parecer técnico conservado. | Não observado |
| 03 | Negócio33 — mandato e divulgação | 1 | [Abrir](https://portal-investidor.test:18445/minhas-oportunidades/33/edit) — Conferir os campos de mandato, histórico, teaser e divulgação do negócio 33 e a distinção entre promotor real e operadora. | Não observado |
| 04 | Mapa público e carteira | 1 | [Abrir](https://portal-investidor.test:18445/oportunidades?view=map) — Observar filtros, legenda e ausência de coordenadas privadas no mapa público; abrir o corredor da carteira e conferir relações ou ausência explícita. | Não observado |
| 05 | Parceria34 — seis obrigações | 1 → 2 | [Abrir](https://portal-investidor.test:18445/minhas-oportunidades/34/edit) — Observar e recuperar as seis obrigações: laborais, calendário, gestão, matérias reservadas, saída e impasse; conferir os três pareceres afetados e o cadastral empresarial conservado, até disponibilização restrita. | Não observado |
| 06 | Franquia56 — licença, formatos e acesso | 1 → 2 → 4 | [Abrir](https://portal-investidor.test:18445/minhas-oportunidades/56/edit) — Na franquia 56, observar licença/marca/titular/território/exclusividade, abrir JPEG/PDF e descarregar DOCX/XLSX; conferir WebP, hierarquia/ausência, os pareceres afetados, disponibilização restrita e recuperação; confirmar recusa a QA23. | Não observado |
| 07 | Anúncio antigo — workflow | 1 → 2 | [Abrir](https://portal-investidor.test:18445/investidor/negocios/172aa874-98fc-4bf6-b78f-d2e9a386d345) — No anúncio antigo preparado, observar a entrada de revisão pelo dashboard e submissão → correção → ressubmissão → aprovação → publicação, com teaser público sem dados privados. | Não observado |
| 08 | Interesse empresarial — países e estatísticas | 1 → 3 | [Abrir](https://portal-investidor.test:18445/negocios/simulacao-qa-b7-tres-papeis-definidos-pela-tempo-67d806991b) — Observar empresa, país da entidade e origem no interesse do anúncio; conferir recibo, recuperação, filtros e denominador após a submissão, incluindo repetição da mesma tentativa sem duplicar. | Não observado |
| 09 | Organização — países distintos | 1 | [Abrir](https://portal-investidor.test:18445/investidor/profile) — Conferir país mestre ZA, declaração histórica FR, residência PT e origem BR nos respetivos ecrãs, preservando o snapshot anterior. | Não observado |
| 10 | Dossier — vínculo fundiário | 1 | [Abrir](https://portal-investidor.test:18445/investimentos/b3e162da-0f9e-4ed4-8e66-c1febcb8504b) — Observar preparar/continuar Terra e DUAT → guardar no pedido ligado → voltar ao dossier → recuperar noutra sessão, sem transferir o vínculo para outro dossier. | Não observado |
| 11 | Entidade fundiária — seletores e anexos | 1 → 3 | [Abrir](https://portal-investidor.test:18445/investidor/terra-duat/01a13504-61d9-7033-89dd-40563f857517) — No apoio fundiário de entidade, observar quatro seletores e país ZA/origem PT separados da localização MZ; abrir ata/esboço/fotografia. QA17 descarrega pelo link administrativo corrigido. | Não observado |
| 12 | Balcão — território, recibo e revogação | 1 → 2 | [Abrir](https://portal-investidor.test:18445/balcao-virtual/pedidos/8a42ee0d-e47e-4f27-9e73-b986d0345058) — Conferir localidade/fonte, ausência explícita de camadas públicas, anexo e recibo TXT; QA24 revogado recebe recusa e QA25 atribuído recupera os mesmos recursos. | Não observado |
| 02 | Coedição de 15 — revogação | 4 | [Abrir](https://portal-investidor.test:18445/perfis/gestao) — Revogar pela interface somente o papel Promotor/coeditor de QA22; conferir perda da sessão anterior e recusa de edição do rascunho 15 após nova sessão, preservando a leitura como Validador. | Não observado |
| 01 | Projeto30 — licença e materialidade | 1 → 2 | Consulta QA24/QA25 e histórico QA reconciliados: ciclo4 da licença, legal reaberta/revista, assinatura técnica anterior conservada, aprovação24 e disponibilização interna25 já registadas. Estado atual submetido/v55/ciclo7 e pedido de arquivo preservados; nenhuma transição repetida. Evidência: line01-passed-history-reused-20261015.json. | **Passou — encerrada** |
| 03 | Negócio33 — mandato e divulgação | 1 | [Consultar](https://portal-investidor.test:18445/minhas-oportunidades/33/view) — Mandato, histórico, teaser, divulgação e distinção entre promotor real e operadora conferidos pelo responsável. Não repetir os pontos confirmados nem o Workflow. Submetido/v67 no diagnóstico de 15/10: `/edit` recusa QA21; consulta sem alterar estado/permissões. | QA21: **passou**, confirmação manual de 15/10; 403 anterior preservado como histórico |
| 04 | Mapa público e carteira | 1 | [Mapa público](https://portal-investidor.test:18445/oportunidades?view=map) — Filtros, legenda e ausência de coordenadas privadas, bem como relações ou ausência explícita no [corredor da carteira](https://portal-investidor.test:18445/carteira/06b2d5d7-98ad-48db-b732-8a70b2f5eb4c), confirmados manualmente no âmbito orientado. Não repetir. | **Passou**, confirmação manual de 15/10 |
| 05 | Parceria34 — seis obrigações | 1 → 2 | QA21 já aceite. Histórico ciclo7: financeira/governação/legal revistas, corporate_screening anterior preservado, aprovação24 e disponibilização interna25. Apresentação/acesso atual QA24/QA25 confirmados; v66/correções solicitadas e publicação anterior preservados, sem repetir decisões. Evidência: line05-passed-history-reused-20261015.json. | **Passou — encerrada** |
| 06 | Franquia56 — licença, formatos e acesso | 1 → 2 → 4 | JPEG/WebP individuais e quatro seletores após reload passaram. Histórico seletivo, assinatura financeira/confidencialidade preservada e aprovação24/disponibilização interna25 reutilizados. QA23:403 na ficha e JPEG. Evidência: line06-passed-20261015.json. | **Passou — encerrada** |
| 07 | Anúncio antigo | Consolidado | Publicação v12 e confidencialidade aceites preservadas. Subcritério: não demonstrado — pedido de correção inespecífico; limitação aceite expressamente pela Tempo em15/10, sem novo ensaio/reabertura. | **Encerrada com ressalva aceite** |
| 08 | Interesse empresarial — países e estatísticas | 1 → 3 | QA17 autenticado (Synthetic cartography manager QA, identidade17 conferida por leitura) recuperou o recibo IR-2026-01M4ZNZZ33ZMBWKP1NQ6JGFB0Z/24 e confirmou denominação «QA negocio paises legado», tipo empresa, país MZ e origem BR em campos separados, ligados ao anúncio B7 correto. Lista com recibo + país MZ + origem BR apresenta 1 registo. Agregados BR observados e conferidos por leitura QA: manifestações 6, Balcão 0, negócios submetidos 3. Conjunto: todos os registos elegíveis atuais, sem filtro temporal; não é contagem diária/mensal. Agregados filtram origem, não país nem pesquisa pelo recibo; país/pesquisa aplicam-se à lista. Manifestações excluem eliminados logicamente e incluem apoio fundiário; Balcão/negócios excluem draft/cancelled, preservando os âmbitos do repositório. Coleções não se somam como investidores únicos. Denominador global de manifestações 18. Ausência de duplicação reutiliza business-country-after.json (mesma chave/recibo e agregados estáveis), conforme autorização expressa; nenhum reenvio nesta verificação. Linha 08 passou no âmbito do roteiro. Evidência: `line08-QA17-statistics-20261015.json`. | **Passou — linha encerrada**, idempotência técnica reutilizada sem reenvio |
| 09 | Organização — países distintos | 1 | QA21 já estava autenticado ao iniciar a verificação (substituição de QA17 feita antes da observação; nenhum novo logout/login pelo agente). Perfil: cadastro mestre da organização ZA/África do Sul, v5, separado da declaração empresarial FR e cópia histórica da organização v2. Mesmo processo 01a127a9-4454-731c-bb15-fc89649120ea, submetido/v3: «País de constituição da entidade» FR/França, «País de residência» PT/Portugal e «País de origem declarado desta solicitação» BR/Brasil, com aviso de independência e preservação da cópia histórica. Perfil e processo atualizados por reload; valores e rótulos permaneceram. Nenhuma edição, gravação, reutilização de país, mensagem ou reenvio. Linha 09 — rótulos e recuperação visual passaram. Evidência: `line09-visual-passed-20261015.json`. | **Passou — linha encerrada** |
| 10 | Dossier — vínculo fundiário | 1 | Após logout observado, credenciais QA21 aceites e MFA concluído pelo responsável, nova sessão QA21 abriu o dossier de agronegócio b3e162da-0f9e-4ed4-8e66-c1febcb8504b e recuperou pelo link Preparar Terra e DUAT o mesmo pedido TERRA-2026-NJYDFHOC/01a1363a-ce9c-71fb-a782-20b3062f6908, versão 2, descrição gravada preservada e Voltar ao dossier apontando ao mesmo projeto. Sem editar, guardar novamente ou criar outro pedido. Conjugado com gravação/retorno/vínculo já confirmados e provas técnicas de isolamento preservadas, linha 10 passou e fica encerrada. Evidência: `line10-new-session-passed-20261015.json` e snapshots associados. | **Passou — linha encerrada** |
| 11 | Entidade fundiária — seletores e anexos | 1 → 3 | Verificação visual QA21 no mesmo TERRA-2026-Y4LXZOV7/v10, incluindo reload: Província Cabo Delgado, Distrito ANCUABE, Posto administrativo ANCUABE, Localidade ANCUABE-SEDE, com os quatro IDs exatos e controlos ativos. Nenhuma seleção manual, gravação, edição de dados ou reenvio. Leitura SQL READ ONLY posterior confirma versão10, hash do payload cifrado e IDs idênticos ao início. TypeScript e build QA passaram; regressões de chegada tardia dos IDs, HTTP503 e pai incompatível passaram em harness isolado com componente real (sem mutação de browser/base); erro forçado não foi ensaiado no pedido real. Downloads QA21/QA17, países ZA/PT e restantes confirmações preservados sem repetição. Conforme âmbito confirmado pelo responsável (faltava apenas recuperação visual), linha 11 passou e fica encerrada. Evidência: `line11-recovery-passed-20261015.json`. | **Passou — linha encerrada** |
| 12 | Balcão — território, recibo e revogação | 1 → 2 | Pedido preparado 8a42ee0d-e47e-4f27-9e73-b986d0345058 e dossier b0e591ab-c6b3-41ea-b3ed-cd9efa575bc5 reutilizados sem novo envio. QA21: localidade ANCUABE-SEDE na hierarquia Cabo Delgado/Ancuabe/Ancuabe, fonte «Cadastro territorial QA: contexto administrativo INE, não parcela nem direito real» e indicação explícita de zero limites administrativos acessíveis, sem inferir parcela/camadas públicas inexistentes. Recibo TXT BV-2026-8A42EE0DE47E4F279E73B986D0345058 aberto e lido, snapshot v5; PDF existente descarregado, renderizado e aberto: esboço sintético sem validade jurídica, hash igual ao snapshot. QA24 autenticado após revogação já existente recebeu 403 no pedido, mesmo anexo e recibo. QA25 atualmente atribuído recuperou o mesmo pedido e descarregou anexo com hash idêntico e recibo idêntico por bytes ao de QA21. SQL READ ONLY confirmou titular21/autorizado, QA24 recusado e analista25/autorizado. Não repetida reatribuição/revogação, novos documentos, submissões, mensagens ou provas técnicas já aceites de old-session/replay. Linha 12 passou e fica encerrada. Evidência: `line12-passed-20261015.json`. | **Passou — linha encerrada** |
| 02 | Coedição15 — revogação | 4 | Por último: QA27 revogou somente Promotor22; demais atribuições intactas. Novo login22: edição15 recusada403 e leitura Validador30 mantida. Sessão anterior: prova técnica401 reutilizada, sem sessão ativa para observação nova. Evidência: line02-passed-20261015.json. | **Passou — encerrada** |
O link Abrir corresponde à primeira conta da linha. As rotas de revisão/gestão e recuperação estão no detalhe por fase da entradaQA, para não enviar QA21 a ecrãs administrativos. As ações/limites de cada linha permanecem exatamente os do roteiro reconciliado. Detalhe por conta em `acceptance-396c-results.json`, campo `fixed_passage_lines`. A linha composta permanece não observada até as partes necessárias estarem observadas; um resultado parcial positivo nunca é apagado nem repetido. Se falhar, parar apenas o trecho dependente, registar o erro e corrigir/verificar somente esse comportamento em QA.
@@ -1,3 +1,368 @@
<!-- 20261015_Tempo_B_activation_authorized -->
## Autorização de ativaçãoB recebida — backup fresco concluído; sessão real pendente
A instrução expressa «A Tempo autoriza» aceita a proposta imediatamente anterior: B-final-fabf722bc8c6+suplementoC137 e limitações documentadas, somente190000 se ausente pela ação autenticada, flag após verificação, backup/restauro fresco e reversão, COUNTRY02/serviços/dados preservados. Referência B-activation-Tempo-authorization-20261015.json. Não solicitar novamente esta autorização.
Backup atual do destino investemoz:5432 restaurado em clone55441*_test:295 tabelas/31 sequências correspondentes,815 ficheiros copiados/restaurados por hash,4 documentos existentes e nenhum ausente; origemREAD ONLY. Fontes/build/configuração e ACLs preservados em cópia privada fora do webroot.36 fontes e ativos da candidata+base preparados em staging privado com hashes verificados; candidata original e suplemento imutáveis.
A aba EntregaB abriu o login do destino. Solicitado ao responsável apenas completar login/MFA da conta real já autorizada; não há sessão real disponível ainda. Não usar contasQA no ativo, não inventar ator nem contornar a ação autenticada. Antes dessa condição, não foi iniciada manutenção nem trocado código/build;190000 e flag permanecem intactos. Estado B-activation-current-status-20261015.json. Provas dos12 critérios não repetidas. Retomar pela sessão real, conferir gates/proveniência, depois executar a sequência autorizada; renovar backup se o intervalo/estado do destino o exigir.
<!-- 20261015_priority_proposal_after_B -->
## Proposta de prioridade após B — sujeita à decisão da Tempo
Registar como proposta, sem alterar automaticamente a ordem aprovada:1 disponibilizarB após autorização e acompanhar uso real;2 orientação/conteúdo educativo do legado, começando pelo agronegócio, ligando conteúdo público→setor/território→ideia→dossier→apoio;3 ferramentas de decisão fiscal/contributivo/fundos/comparação;4 checklists versionadas, indicadores de utilização e acompanhamento interno. Não iniciar frentes em paralelo. Países/mapas/documentos acompanham cada consumidor incluído, reutilizando provas aceites e tratando lacunas específicas; sem auditoria geral nova. Fiscal, fundos, comparador societário, capitalização e outros pedidos mantêm os IDs/pendências na matriz existente, sem descarte.
### Ficha delimitada — Orientação e legado, piloto agronegócio — 15/10/2026
Preparação solicitada pela Tempo após a disponibilização B. Usar os requisitos existentes AUD-LEG-01–07 e AUD-LIB-01–02; nenhum novo backlog, estado funcional promovido ou reabertura B. Não iniciar outros setores, fiscal, fundos ou comparadores neste recorte. A autorização atual abrange preparação; não publica conteúdo nem altera o ativo.
| Trecho | Reutilização comprovada ou encontrada | Saldo desta entrega |
| --- | --- | --- |
| Agronegócio público → conteúdo educativo | Rotas `/explorar/agronegocio` e `/agronegocio`; `LegacyContent` lê a biblioteca existente; artigo `legacy-tempo-post-171985-20260420`, imagem e manifesto privados preparados. Provas QA anteriores de pesquisa, corpo, imagem, fontes, foco e móvel 390 px. | O leitor está limitado a testing/127.0.0.1:55441/_test no método `available()`. O destino contém zero documentos `legacy-tempo-%` e retorna indisponível pelo serviço. Preparar gate de disponibilização próprio e lote mínimo privado, sem promover configuração QA a produção nem copiar base QA. |
| Contexto setorial/territorial | Correspondência explícita ao setor agronegócio; menções territoriais, links para corredores e zonas; oportunidades publicadas independentes do artigo. | Conferir o setor e os destinos efetivos no ambiente de entrega. Não deduzir relação projeto/artigo, parcela, coordenadas ou geometria a partir de menção textual. Países/mapas/documentos limitados a estes consumidores. |
| Conteúdo → ideia → dossier | `LegacyContentController`, rotas autenticadas, referência versionada, retorno ao artigo e contexto privado. Provas QA anteriores de novo login, referência única e isolamento. B disponibilizou o percurso, 190000 e flag já verificados. | Conferir compatibilidade do leitor público com o percurso agora ativo; preservar origem e retorno. Não reinstalar 190000, não repetir os 12 critérios nem criar outro dossier para preencher provas já aceites. |
| Dossier → apoio | Percurso de cinco fases/19 etapas; pedidos contextuais e vínculo Terra/dossier já aceites na linha 10. | Identificar o serviço/versionamento efetivamente publicado e o destino de apoio deste recorte. Não publicar serviços automaticamente nem criar pedido duplicado. Distinguir conteúdo educativo do setor do módulo Educação e competências. |
Dependências concretas a resolver antecipadamente:
1. Disponibilização do leitor: a restrição a QA é escolha técnica de implementação, não regra organizacional da Tempo. Preparar em QA uma configuração explícita para leitura autorizada no destino, preservando autenticação só ao guardar, sanitização e confidencialidade; não alterar o gate no ativo nesta preparação.
2. Conteúdo mínimo: artigo e imagem existentes em `storage/app/private/document-import-staging/legacy-agronegocio/`. Conferir versão, bytes, origem, links/anexos do recorte e autorização de divulgação registada. Inventariar o acervo completo existente antes da seleção; o histórico 92 URLs/50 versões não equivale a publicação integral. Fontes oficiais já aceites não exigem nova validação de credibilidade.
3. Instalação documental: reutilizar `documents:import-batch` com preview/hash/duplicados/conflitos e rascunhos privados. O importador não publica. Identificar a conta real e a ação autenticada de publicação na biblioteca, verificar scan dos mesmos bytes/worker e direitos por ficheiro. Não executar scripts QA com utilizadores sintéticos no destino. Backup/restauro fresco apenas próximo de futura execução autorizada.
4. Ligações: levantar por leitura a correspondência setorial, recursos públicos e versão de serviço de apoio; ausência deve aparecer como tal. Não associar territórios automaticamente nem exigir nova ACL de sala para leitura de artigo público.
Resultado visível esperado: visitante encontra a entrada agronegócio, lê o artigo e a imagem com fonte, consulta o contexto disponível, inicia/continua uma ideia, autentica para guardar e recupera no mesmo dossier a referência de origem e a ligação ao apoio aplicável.
Esforço: o saldo confirmado concentra-se na adaptação do gate, preparação do lote mínimo e ligações/publicação. A faixa histórica 6–10 h de AUD-LEG/LIB é referência do lote, não orçamento fechado deste piloto. A estimativa de implementação depende da comparação de versões/recursos e do serviço publicado; não somar novamente aceitação do dossier, Terra, países ou B. Próximo trabalho preparatório: manifesto mínimo com hashes, comparação origem/destino e mapa exato de disponibilização/reversão, seguido apenas de correções QA identificadas.
Evidências reutilizadas: `legacy-content-browser-qa.json`, `legacy-content-browser-persistence-qa.json`, `legacy-sectors-browser-qa.json` em `storage/app/private/investmoz-v2/portal-audit/`; linha 10 encerrada e resultado B preservados. Leitura atual do destino: `outputs/investmoz-audit-current-20261012/orientacao-legado-active-readonly-20261015.json` (transação READ ONLY, zero escritas ativas). Esta ficha delimita o recorte; não declara cumpridos todos os requisitos AUD-LEG/LIB.
<!-- 20261015_C137_sequence_supplement -->
## SuplementoC137 e sequência operacional corrigida
room.tsx acrescentado ao suplemento, hash coerente com chunk da candidata; fonte36 e mapa de reversão atualizado. Candidata base permanece imutável. Proposta final reúne entregaB/C137 com limitação visual expressa, somente190000 ausente pela ação autenticada, flagtrue após verificação e backup/restauro fresco próximo da execução. Não é autorização recebida. Sequência corrigida: flagfalse → manutenção/troca → saída de manutenção → instalação autenticada → verificar → habilitar. Nenhuma exceção de manutenção presumida. Compatibilidade intermediária documentada com prova técnica anterior de pathfalse e leitura dos guards/rotas independentes do instalador; não atribuída a novo HTTP com schema ausente. Nenhuma repetição dos12 critérios, funcionalidade nova, build ou alteração ativa. Manifesto/ZIP/hashes e recibo em B-suplemento-C137-sequencia-final-20261015.
<!-- 20261015_Tempo_operational_documents -->
## Documentos de decisão — tratamentos distintos de190000 eC137
Arranque no clone encerra recuperação operacional;12 critérios mantêm-se encerrados.190000 é dependência de instalação já prevista; somente ausente, pela ação autenticada. C137 é alargamento de âmbito a deliberar: proposta discrimina comportamento, fonte/chunks, provas técnicas e limite visual, bem como reversão sem reatribuir partilhas. Candidata/hash preservados. PROPOSTA-UNICA-TEMPO.md, PROCEDIMENTO-EXATO.md e RECIBO-INTEGRIDADE.json em B-preparacao-operacional-documentos-Tempo-20261015 e anexados a página privada ChatGPT para leitura pelo responsável. Backup/restauro fresco do destino somente próximo da execução. Nenhuma ativação autorizada ou executada.
<!-- 20261015_B_operational_preparation -->
## Preparação operacional — arranque no clone passou; candidata mantida
Kernel Laravel/renderização/Vite e GET /up,/login,/oportunidades retornaram200 sobre b_final_restore_20261015_124723_test:55441, com conexãoREAD ONLY, sessões/cachearray e conectores externos/SSR desativados apenas no clone privado. A montagem usa compilação base mais delta; CSS/fontes requeridos já constam do ZIPbase incluído. Nenhuma recompilação ou alteração da candidata B-final-fabf722bc8c6; SHA256original c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78 preservado. Não equivale a ensaio PHPweb/TLS/worker do ativo.
Destino consultado READ ONLY: investemoz:5432,35 fontes a substituir,769 recursos atuais preservados,82 migrações, DevToolsOFF e locksComposer/NPM/dependências iguais. Duas colunas existentes apenas no clone: investor_journeys.path_definition_id e journey_steps.path_detail, migração190000 já prevista para percurso integrado mas ausente do destino. Instalação autenticada /management/balcao-install e flag são ações separadas; não aplicadas. Outra diferença operacional: C137 de retirada de partilha em sala encerrada já está compilado na base/candidata, mas salas/C137 ficaram fora do âmbitoB e a fonte room.tsx não está no delta35. Não inferir aceitação, não introduzir código nem remover silenciosamente da candidata. Ativação não liberada até decisão expressa desse alcance.
Procedimento exato e mapa por ficheiro preparados no suplemento B-preparacao-operacional-20261015, com backup privado do código/bundle atual para reversão; backup/restauro fresco do destino será obrigatório antes de eventual troca, não substituído pelo dumpQA. Proposta única à Tempo: ativação condicionada à delimitação190000/C137 e às guardas documentadas; nenhuma execução autorizada. Pacote completo inclui a candidata original imutável; recibo B-operational-integrity-receipt-20261015.json verifica CRC/hashes recursivos, manifestos, ativosVite/fontes e ausência de credenciais conhecidas. Os12 critérios e aceitação funcional, incluindo ressalva07, mantêm-se encerrados; isto é preparação operacional, não reabertura da auditoria.
<!-- 20261015_B_final_candidate_review -->
## Opção B — candidata final para revisão; limitação da linha07 aceite pela Tempo
Decisão expressa da Tempo em 15/10: aceita «não demonstrado — pedido de correção inespecífico» na linha07, sem novo ensaio nem reabertura. A limitação permanece identificada; não foi convertida em prova de correção nem em falha funcional. Publicação v12 e confidencialidade preservadas. Linhas01–12 encerradas nesta passagem, linha07 com ressalva aceite. Não repetir provas aceites. Referência: line07-Tempo-limitation-accepted-20261015.json.
Candidata B-final-fabf722bc8c6, base396c691930bc mais deltas QA reconciliados: 35 fontes e173 ficheiros de build efetivamente referenciados, incluindo feedback de submissão/triagem, correções C147/C148 e recuperação territorial da linha11. Manifesto identifica hashes, proveniência e limitações; fontes/bundle do ativo mantêm hashes. Sem nova compilação ou ensaio funcional. O âmbitoB aprovado e a matriz existente mantêm-se; isto não encerra requisitos fora do âmbito.
Backup/restauro correspondente: snapshot QA consistente restaurado em b_final_restore_20261015_124723_test:55441; 295 tabelas e31 sequências iguais por conteúdo/hash, 133 ficheiros documentais e208 fontes/build copiados/restaurados por hash. Dump, configuração QA/chave e ficheiros privados ficam em diretório local fora do webroot e do ZIP. Não executado arranque da aplicação na base restaurada; não equivale a ensaio de ativação no ativo. Procedimento de recuperação inclui dependência da base/runtime existentes e proíbe repor concessões revogadas sem decisão expressa.
Resultado: pacote final para revisão, com manifesto, fonte/build, provas selecionadas, limitações e recibo/procedimento de backup/restauro. **Ativação no ativo não autorizada**; nenhuma ação de implantação, migração, flags ou serviços no ativo. Próxima ação é revisão da candidata pela Tempo, sem nova ronda de testes aceites.
<!-- 20261015_lines06_02_closed -->
## Linhas 06 e 02 encerradas — saldo desta passagem
Linha06/Franquia56: QA21 abriu individualmente o JPEG qa-B8-photo.jpg existente (download autorizado, 800×600, identificação de simulação sem pessoas/local real) e a derivada WebP aa492906-ffd6-4acb-93c0-a04c2c9b5a9d no navegador (fundo verde e identificação Synthetic QA consumer 20261012). A WebP deriva do PNG já existente, não do JPEG distinto; não criar outro recurso para os confundir. Quatro seletores recuperados e confirmados após reload no mesmo recurso territorial v3: Cabo Delgado → ANCUABE → ANCUABE → ANCUABE-SEDE, sem guardar ou selecionar novamente.
Histórico QA READ ONLY: marca/licença e legal seletivamente revistas por QA24 no ciclo6; financeiro e confidencialidade preservam hash, autor e data iguais ao ciclo5. Aprovação24 em 13/10 16:57:27 UTC e disponibilização interna25 às 16:57:40 usam o mesmo hash. QA24/QA25 acedem atualmente à ficha restrita; QA23 autenticado recebeu403 na mesma ficha e no mesmo JPEG. v64/needs_information e publicação anterior preservadas; preparação visual posterior não foi convertida em novo ciclo. PDF/DOCX/XLSX e recuperação da ficha já aceites não repetidos. Linha06 passou; evidência `line06-passed-20261015.json` e ficheiros referenciados.
Linha02, executada por último: QA27 revogou na interface apenas a atribuição Promotor/coeditor ativa de QA22, id82548503-1e60-4259-a642-290ac20c7388. Hashes READ ONLY de todas as outras atribuições iguais antes/depois, incluindo todos os papéis Validador de QA22. Nenhuma nova atribuição nem reabilitação. QA22 voltou a autenticar-se: /15/edit recusado403 e /30/view acessível como Validador. Não havia sessão anterior QA22 ativa no início (zero sessões antes/depois da revogação); a invalidação da sessão anterior reutiliza explicitamente a prova técnica aceite option-B5-coeditor-revoke-HTTP.json (401), sem a atribuir a observação visual nova. Linha02 passou conjugando essa prova anterior com revogação visual atual e verificação após novo login. Evidência `line02-passed-20261015.json`, comparações READ ONLY e snapshots QA27/QA22.
Saldo delimitado: linhas01–06 e08–12 encerradas. Na linha07 resta apenas «não demonstrado — pedido de correção inespecífico», para a Tempo decidir aceitar a limitação ou solicitar ensaio complementar delimitado; nenhum novo ciclo para preencher essa lacuna. Publicação v12, confidencialidade, ficheiros, restantes confirmações e delta QA da linha11 no manifesto preservados. Este saldo da passagem não encerra automaticamente todos os requisitos funcionais da matriz nem declara ativação no ativo.
<!-- 20261015_line05_history_closed -->
## Linha 05 — Parceria34 encerrada sem repetir decisões
Consulta autenticada QA24 e QA25 confirma apresentação atual: financeira, governação e legal reabertas, corporate_screening conservado, disponibilização restrita mantida e acesso à mesma ficha. Histórico persistido consultado exclusivamente READ ONLY em QA confirma ciclo7/conteúdo9: financial_review revista por QA24 às 12:01:47, partnership_governance_review às 12:01:51 e legal_tax_due_diligence às 12:04:42 de 13/10 UTC. corporate_screening preserva hash, autor24 e data 10/10 22:07:11 UTC iguais ao ciclo anterior. Aprovação independente24 em 13/10 12:04:46 e disponibilização interna25 às 12:04:55 referem o mesmo hash da variante. Provas HTTP B6 e consulta/recuperação QA21 das seis obrigações reutilizadas.
Estado atual v66/needs_information resulta de request_revision por QA21 em 13/10 17:47:47 para preparar o ensaio visual; publicação anterior permanece. Não foi criada nova ressubmissão, parecer, aprovação, publicação ou alteração de dados para repetir o que o histórico já demonstra. Datas/assinaturas provêm do histórico persistido, sem alegar que a lista simplificada de gestão as apresenta visualmente. Linha05 passou no âmbito delimitado e fica encerrada. Evidência: `line05-passed-history-reused-20261015.json`, `line05-history-readonly-20261015.json` e snapshots QA24/QA25.
Próximo trecho: linha06 — Franquia56, apenas JPEG/WebP individualmente, seletores/hierarquia e trechos de revisão/disponibilização/recusa ainda sem prova, começando pelo histórico. Depois linha02, revogação de QA22 por último. Linhas01/03/04 e08–12 encerradas; linha07 conserva apenas limitação documental para Tempo. Publicação v12, confidencialidade e correção QA da linha11 no manifesto preservadas.
<!-- 20261015_line01_history_closed -->
## Linha 01 — encerrada por histórico reconciliado e consulta QA24/QA25
QA24 autenticado consultou Projeto30; QA25 autenticado confirmou «Disponibilizada com acesso restrito — perfis e organização autorizados». Leitura isolada QA READ ONLY confirma o ciclo 4/revisão de conteúdo 9 da licença: legal reaberta conforme prova HTTP B3 existente, revista por QA24 em 13/10 às 08:35:52 UTC com anexo próprio 47185cd8-107c-48dd-9c14-abb6283cacb9; parecer técnico conservou hash, autor24 e data 11/10 11:25:03 UTC iguais à base anterior. Aprovação QA24 às 08:35:57 e disponibilização interna QA25 às 08:36:13 de 13/10 têm o mesmo hash. Não repetir essas decisões.
Estado atual separado: submetido/v55, ciclo7 posterior, ambos os pareceres conservados e publicação restrita anterior intacta; pedido de arquivo registado em 15/10 aguarda decisão. Não foi decidido o arquivo nem encerrado/aprovado esse ciclo posterior apenas para concluir a variante. O histórico de gestão visível lista alterações do rascunho; os detalhes das decisões/assinaturas foram recuperados do histórico persistido READ ONLY, sem os apresentar como observação visual. QA21 já aceite não repetido. Linha 01 passou no âmbito delimitado e fica encerrada; nenhuma edição, submissão ou transição nova. Evidência: `line01-passed-history-reused-20261015.json`, `line01-history-readonly-20261015.json` e snapshots QA24/QA25. As provas técnicas B3 foram reutilizadas, não reexecutadas.
Próximo trecho: linha 05 — Parceria34, QA24/QA25; consultar primeiro histórico, verificar financeira/governação/legal afetadas e corporate_screening conservada, reaproveitando aprovação/disponibilização já demonstradas. Ordem restante 05 → 06 → 02, revogação de QA22 por último. Linhas 03/04 e 08–12 encerradas; linha07 conserva apenas a limitação documental para Tempo. Publicação v12, confidencialidade e delta QA da linha11 no manifesto preservados.
<!-- 20261015_lines01_06_balance -->
## Saldo atual das linhas 01—06 — confirmações anteriores reutilizadas
Decisão expressa do responsável: linhas 08—12 encerradas; linha 07 mantém apenas —não demonstrado — pedido de correção inespecífico—, para decisão da Tempo. Publicação v12 e confidencialidade aceites preservadas; não criar novo ciclo para suprir a lacuna. Este saldo atual prevalece sobre pend—ncias hist—ricas abaixo e não constitui novo ensaio.
| Linha | Aceite e preservado | Ainda não observado |
| --- | --- | --- |
| 01 — Projeto30 | QA21: campos da licença e documento aberto e leg—vel. | QA24/QA25: legal afetada, técnica conservada; apenas transições desta variante ainda sem prova. |
| 02 — Coedição15 | Provas técnicas anteriores preservadas. | QA27 revoga somente Promotor/coeditor de QA22; QA22: sessão anterior invalidada, edição de 15 recusada após novo login e leitura como Validador preservada. Executar por —ltimo. |
| 03 — Negócio33 | Mandato, histórico, teaser, divulgação e promotor real: passou, encerrada. | Nenhum. |
| 04 — Mapa/carteira | Filtros, legenda, exclusão de dados privados e relações ou ausência explícita: passou, encerrada. | Nenhum. |
| 05 — Parceria34 | Apresentação e recuperação das seis obrigações por QA21; nenhuma nova gravação inferida. | QA24/QA25: financeira, governação e legal afetadas; corporate_screening conservada; aprovação/disponibilização restrita desta alteração. |
| 06 — Franquia56 | Ficha recuperada, PDF aberto/descarregado e DOCX/XLSX descarregados/abertos. | QA21: JPEG/WebP individualmente e comportamento dos seletores/hierarquia. QA24/QA25: marca/licença e legal afetados, financeiro/confidencialidade conservados; aprovação/publicação restrita desta variante. QA23: recusa na mesma ficha/recurso após disponibilização. |
Saldo: duas encerradas (03/04), tr—s parciais (01/05/06), uma não observada (02). Próximo trecho: linha 01, QA24 — QA25, pela consulta /minhas-oportunidades/30/view, conferindo primeiro o histórico e as provas existentes. Não repetir QA21, não usar /edit para contornar o estado, nem repetir transições j— demonstradas. A revogação da linha 02 permanece por —ltimo, conforme roteiro. Não há novo envio, alteração de dados ou transição nesta reconciliação. Evidência estruturada: `outputs/investmoz-audit-current-20261012/lines01-06-balance-20261015.json`; resultados existentes atualizados com o saldo sem apagar histórico. Correção QA da linha 11 continua registada no manifesto existente para empacotamento final.
<!-- 20261015_line12_passed -->
## Linha 12 — Balcão passou; linha encerrada
Pedido preparado 8a42ee0d-e47e-4f27-9e73-b986d0345058 e dossier b0e591ab-c6b3-41ea-b3ed-cd9efa575bc5 reutilizados sem novo envio. QA21: localidade ANCUABE-SEDE na hierarquia Cabo Delgado/Ancuabe/Ancuabe, fonte «Cadastro territorial QA: contexto administrativo INE, não parcela nem direito real» e indicação explícita de zero limites administrativos acessíveis, sem inferir parcela/camadas públicas inexistentes. Recibo TXT BV-2026-8A42EE0DE47E4F279E73B986D0345058 aberto e lido, snapshot v5; PDF existente descarregado, renderizado e aberto: esboço sintético sem validade jurídica, hash igual ao snapshot. QA24 autenticado após revogação já existente recebeu 403 no pedido, mesmo anexo e recibo. QA25 atualmente atribuído recuperou o mesmo pedido e descarregou anexo com hash idêntico e recibo idêntico por bytes ao de QA21. SQL READ ONLY confirmou titular21/autorizado, QA24 recusado e analista25/autorizado. Não repetida reatribuição/revogação, novos documentos, submissões, mensagens ou provas técnicas já aceites de old-session/replay. Linha 12 passou e fica encerrada.
Evidências consolidadas: `line12-passed-20261015.json`. A correção QA da linha 11 integra o manifesto existente acceptance-396c-manifest.json como delta pós-base, com hashes de fonte/cópia de revisão/manifesto de build, testes e reversão; inclusão obrigatória no empacotamento final. Isto não declara candidata final nem ativação. Restantes confirmações e limitação documental da linha 07 preservadas. A abertura file:// do PDF no navegador foi recusada pela política; não contornada: leitura/renderização local do ficheiro descarregado usada como alternativa sem navegador.
<!-- 20261015_line11_recovery_passed -->
## Linha 11 — recuperação corrigida em QA e verificada; linha encerrada
Correção exclusivamente QA em ParcelEditor: o carregamento anterior executava uma vez com dependências vazias e ocultava falhas; não retomava quando os IDs da parcela chegavam/mudavam. Ensaio isolado do componente real reproduziu esse defeito no fonte anterior (nenhum GET após chegada tardia dos IDs); fonte corrigido recupera os quatro níveis. O HTTP concreto da tentativa original não foi capturado e não se lhe atribui status/causa de rede. Recuperação agora depende dos quatro IDs e da tentativa explícita, mantém posições dos níveis, valida ID/tipo/pai, apresenta carregamento e erro acessível com nível/motivo, preservação dos IDs e botão Tentar recuperar novamente. Sem flexibilizar permissões ou regras territoriais. Origem: escolha técnica de recuperação e feedback para falha observada, não nova regra da Tempo.
Verificação visual QA21 no mesmo TERRA-2026-Y4LXZOV7/v10, incluindo reload: Província Cabo Delgado, Distrito ANCUABE, Posto administrativo ANCUABE, Localidade ANCUABE-SEDE, com os quatro IDs exatos e controlos ativos. Nenhuma seleção manual, gravação, edição de dados ou reenvio. Leitura SQL READ ONLY posterior confirma versão10, hash do payload cifrado e IDs idênticos ao início. TypeScript e build QA passaram; regressões de chegada tardia dos IDs, HTTP503 e pai incompatível passaram em harness isolado com componente real (sem mutação de browser/base); erro forçado não foi ensaiado no pedido real. Downloads QA21/QA17, países ZA/PT e restantes confirmações preservados sem repetição. Conforme âmbito confirmado pelo responsável (faltava apenas recuperação visual), linha 11 passou e fica encerrada.
Evidências: `line11-recovery-install-20261015.json`, `line11-recovery-regression-20261015.json`, `line11-recovery-baseline-regression-20261015.log`, `line11-recovery-visual-20261015.json`, `line11-recovery-fixed-20261015.txt`, `line11-recovery-fixed-20261015.png`, `line11-after-recovery-fix-readonly-20261015.json`. Reversão: repor form.tsx e manifesto QA a partir de line11-recovery-before-20261015; chunks anteriores preservados. Fonte/bundle da raiz e matriz mantêm hashes.
<!-- 20261015_line11_investigation_admin_passed -->
## Linha 11 — download administrativo passou; recuperação territorial continua em investigação
Investigação apenas QA, sem selecionar nem guardar: os quatro IDs continuam persistidos, com pais coerentes; consultas individuais do controlador devolveram HTTP200 e a opção exata em todos os níveis. Resposta efetivamente servida no navegador para a província também recuperou Cabo Delgado pelo ID. Bundle QA servido e fonte ParcelEditor confirmam hidratação por quatro GETs sequenciais e estado local inicialmente vazio; HTTP não exitoso/opção ausente interrompe o laço, enquanto exceções são ocultadas por catch vazio. Esse tratamento permite apresentar seletores vazios sem motivo, mas não foi identificada a condição concreta que interrompeu a cadeia na sessão QA21; não atribuir a causa a dados perdidos, IDs inválidos, autenticação, throttle ou catálogo sem prova. Falha de apresentação/recuperação reproduzida continua aberta; nenhuma correção especulativa aplicada. Verificação SQL posterior confirma v10, hash cifrado do payload e quatro IDs iguais ao início. País ZA/origem PT e demais provas mantidos.
QA17 autenticado na página administrativa correta, identidade Synthetic cartography manager QA observada (o MFA já estava concluído quando retomada a página; nenhum código lido ou enviado). Downloads concluídos pelo navegador nos três links /management/terra-duat/01a13504-61d9-7033-89dd-40563f857517/documentos/{id}: ata, esboço e fotografia. Download administrativo autorizado: passou, independente da falha dos seletores. Eventos de download não demonstram leitura/legibilidade do conteúdo. Nenhum anexo novo, reenvio, alteração de estado ou permissão.
Evidência consolidada: `line11-investigation-20261015.json`. Escolha técnica identificada: recuperação assíncrona sem feedback, não requisito organizacional da Tempo. A tentativa de GET pelo curl Windows não chegou ao HTTP por CRYPT_E_NO_REVOCATION_CHECK; não contornada, substituída por navegação normal do browser e consulta isolada do controlador. Provas restantes, publicação v12 e confidencialidade preservadas.
<!-- 20261015_line11_partial -->
## Linha 11 — países/downloads QA21 conferidos; divergência dos seletores
QA21 consultou TERRA-2026-Y4LXZOV7/v10: entidade ZA e origem PT separadas da localização MZ. Downloads dos anexos existentes ata qa-B8-land-minutes.pdf, esboço qa-B8-land-map.pdf e fotografia qa-B8-photo.jpg concluídos por eventos de download do navegador; não inferir leitura/legibilidade do conteúdo. Resumo mostra Cabo Delgado → ANCUABE → ANCUABE → ANCUABE-SEDE. Após carregamento, seletor Província tem 12 opções (inclui Cabo Delgado), mas valor vazio/Seleccione; Distrito/Posto/Localidade desativados e sem seleção. Divergência visual reproduzida em segunda abertura; SQL confirma os quatro IDs persistidos. Não guardar o formulário vazio. Nenhuma edição, gravação, reenvio ou novo anexo. QA21 terminou sessão; credenciais QA17 aceites, MFA por concluir antes de observar download administrativo. Linha 11 parcial: países e downloads QA21 passaram; recuperação dos seletores falhou; legibilidade e download administrativo ainda não observados. Evidências: `line11-partial-20261015.json`, `line11-readonly-20261015.json`, `line11-owner-summary-20261015.txt`, `line11-owner-countries-20261015.txt`, `line11-territory-empty-loaded-20261015.txt`, `line11-territory-empty-20261015.png`. Restantes confirmações preservadas.
<!-- 20261015_line10_new_session_passed -->
## Linha 10 — recuperação após novo login passou; linha encerrada
Após logout observado, credenciais QA21 aceites e MFA concluído pelo responsável, nova sessão QA21 abriu o dossier de agronegócio b3e162da-0f9e-4ed4-8e66-c1febcb8504b e recuperou pelo link Preparar Terra e DUAT o mesmo pedido TERRA-2026-NJYDFHOC/01a1363a-ce9c-71fb-a782-20b3062f6908, versão 2, descrição gravada preservada e Voltar ao dossier apontando ao mesmo projeto. Sem editar, guardar novamente ou criar outro pedido. Conjugado com gravação/retorno/vínculo já confirmados e provas técnicas de isolamento preservadas, linha 10 passou e fica encerrada. Evidência: `line10-new-session-passed-20261015.json` e snapshots associados. Restantes confirmações, publicação/v12 e decisão documental da linha 07 preservadas.
<!-- 20261015_line10_save_return_recovery -->
## Linha 10 — gravação e recuperação do mesmo pedido confirmadas
QA21 reutilizou o pedido preparado TERRA-2026-NJYDFHOC/01a1363a-ce9c-71fb-a782-20b3062f6908, aberto por Preparar Terra e DUAT no dossier Synthetic QA — ideia agronegócio/b3e162da-0f9e-4ed4-8e66-c1febcb8504b. Guardou uma atualização sintética da descrição no mesmo rascunho (v1 → v2), regressou pelo link Voltar ao dossier e reabriu pelo mesmo vínculo; após reload, recuperou a descrição e versão 2. SQL READ ONLY confirma titular21, investor_path_case_id correto, um único pedido nesse contexto e total de pedidos inalterado (6). Nenhum segundo pedido criado, nenhuma submissão oficial ou modificação do anúncio v12. Gravação/retorno/recuperação e vínculo solicitados passaram. Prova técnica anterior de recuperação em nova sessão e isolamento de outro dossier: option-B8-context-access-finish-HTTP.json, preservada; não a descrever como observação visual nova. O trecho visual de recuperação após novo login do roteiro original ainda não foi repetido nem encerrado por esta navegação na mesma sessão. Evidências: `line10-save-return-recovery-20261015.json`, `line10-context-before-20261015.json`, `line10-context-after-20261015.json`, `line10-save-20261015.txt`, `line10-dossier-return-20261015.txt`, `line10-recovered-20261015.txt` e PNG correspondente. Demais confirmações preservadas.
<!-- 20261015_line09_visual_passed -->
## Linha 09 — rótulos e recuperação visual passaram
QA21 já estava autenticado ao iniciar a verificação (substituição de QA17 feita antes da observação; nenhum novo logout/login pelo agente). Perfil: cadastro mestre da organização ZA/África do Sul, v5, separado da declaração empresarial FR e cópia histórica da organização v2. Mesmo processo 01a127a9-4454-731c-bb15-fc89649120ea, submetido/v3: «País de constituição da entidade» FR/França, «País de residência» PT/Portugal e «País de origem declarado desta solicitação» BR/Brasil, com aviso de independência e preservação da cópia histórica. Perfil e processo atualizados por reload; valores e rótulos permaneceram. Nenhuma edição, gravação, reutilização de país, mensagem ou reenvio. Linha 09 — rótulos e recuperação visual passaram. Evidência: `line09-visual-passed-20261015.json` e quatro snapshots antes/depois. Restantes confirmações preservadas.
<!-- 20261015_line09_countries_readonly -->
## Linha 09 — países preparados confirmados por leitura; interface QA21 pendente
Leitura READ ONLY guardada na QA confirmou organização sintética 99964753-2632-4658-a687-8ebc6a178296 com mestre ZA/v5; processo 01a127a9-4454-731c-bb15-fc89649120ea submetido/v3 com declaração FR, residência PT e origem BR. Snapshot histórico FR da organização v2 e declaração empresarial FR preservados; declaração FR não substituiu mestre ZA. Evidência: `line09-countries-readonly-20261015.json`; hash do payload cifrado guardado para comparação posterior. Inspeção de código identifica rótulos separados para país mestre, constituição da entidade, residência e origem, mas não demonstra apresentação visual nem recuperação por QA21. Navegador ligado mantém QA17; necessária sessão QA21 para concluir a conferência visual. Não editar, reenviar ou alterar organização/processo. Restantes confirmações e decisões preservadas.
<!-- 20261015_line08_QA17_passed -->
## Linha 08 — passou; recuperação, filtros e estatísticas conferidos
QA17 autenticado (Synthetic cartography manager QA, identidade17 conferida por leitura) recuperou o recibo IR-2026-01M4ZNZZ33ZMBWKP1NQ6JGFB0Z/24 e confirmou denominação «QA negocio paises legado», tipo empresa, país MZ e origem BR em campos separados, ligados ao anúncio B7 correto. Lista com recibo + país MZ + origem BR apresenta 1 registo. Agregados BR observados e conferidos por leitura QA: manifestações 6, Balcão 0, negócios submetidos 3. Conjunto: todos os registos elegíveis atuais, sem filtro temporal; não é contagem diária/mensal. Agregados filtram origem, não país nem pesquisa pelo recibo; país/pesquisa aplicam-se à lista. Manifestações excluem eliminados logicamente e incluem apoio fundiário; Balcão/negócios excluem draft/cancelled, preservando os âmbitos do repositório. Coleções não se somam como investidores únicos. Denominador global de manifestações 18. Ausência de duplicação reutiliza business-country-after.json (mesma chave/recibo e agregados estáveis), conforme autorização expressa; nenhum reenvio nesta verificação. Linha 08 passou no âmbito do roteiro.
Evidências: `line08-QA17-statistics-20261015.json`, `line08-QA17-detail-20261015.txt`, `line08-QA17-filter-statistics-20261015.txt`, `line08-QA17-stats-20261015.png`, `line08-submission-persisted-20261015.json`, `line08-receipt-20261015.png`, `business-country-after.json`. Publicação/v12, confidencialidade e limitação documental da linha 07 preservadas, assim como todas as outras linhas. Próximo trecho sequencial: linha 09 — Organização, países distintos (mestre ZA, histórico FR, residência PT, origem BR), sem alterar o snapshot nem reenviar.
<!-- 20261015_line08_QA17_login_pending -->
## Linha 08 — conferência QA17 aguarda sessão autenticada
Tentativa pela interface de abrir gestão de interesses com recibo IR-2026-01M4ZNZZ33ZMBWKP1NQ6JGFB0Z, país MZ e origem BR redirecionou para /login. Recuperação visual, filtros, agregados e período/conjunto contado por QA17 ainda não observados; não inferir sucesso pela persistência SQL. Login QA17 necessário na aba Edge mantida para continuação. Nenhuma submissão repetida; provas técnicas existentes de ausência de duplicação preservadas. Evidência: line08-QA17-login-pending-20261015.json. Demais confirmações intactas.
<!-- 20261015_line08_submitted_once -->
## Linha 08 — submissão única e recibo observados
Valores reutilizados por decisão expressa do responsável: «QA negocio paises legado», Empresa, Moçambique/MZ e origem Brasil/BR; rótulo próprio da origem e independência observados. Clique único em Enviar manifestação: «Pedido recebido», recibo IR-2026-01M4ZNZZ33ZMBWKP1NQ6JGFB0Z. Leitura QA READ ONLY confirma empresa/MZ/BR e recibo único; denominador de manifestações 17 → 18 (não investidores únicos). Partilha opcional com proponente não autorizada. Não repetir envio nem criar outra tentativa. Recuperação visual, filtros e estatísticas por QA17 continuam por observar: navegador redireciona gestão para login. Replay não executado, conforme instrução de envio único; provas anteriores de idempotência permanecem preservadas sem novo fecho visual. Evidências: `line08-submission-persisted-20261015.json`, `line08-receipt-20261015.png`. Publicação/v12 e demais confirmações da linha 07 preservadas; nenhuma alteração no ativo.
<!-- 20261015_line08_preflight -->
## Linha 08 — pré-verificação antes da submissão única
Formulário público B7 aberto; tipo Empresa, «País do requerente» e «País de origem declarado desta solicitação» separados, com origem opcional e independente. O manifesto da linha 08 não fixa denominação nem valores dos países. O preparo `business-country-attempt-data.json` contém «QA negocio paises legado», Moçambique/BR, mas destina-se a outro anúncio; não o atribuir silenciosamente a esta linha. Solicitada escolha do responsável para reutilizar esses valores ou indicar os previstos. Nenhum envio executado. QA17 sem sessão no navegador: gestão de interesses redirecionou para login. Leitura QA guardada confirma anúncio B7 publicado e denominador inicial de 17 manifestações; não corresponde a investidores únicos. Evidência: `line08-preflight-readonly-20261015.json`. Confirmação/recibo/recuperação/filtros/estatísticas posteriores ao envio continuam por observar; restantes confirmações e publicação v12 da linha 07 preservadas.
<!-- 20261015_line07_Tempo_decision_pending -->
## Linha 07 — limitação aceite para consolidação; avanço para linha 08
Decisão expressa do responsável nesta conversa, 15/10/2026: limitação da evidência, sem falha funcional demonstrada. Subcritério de atendimento ao pedido: «não demonstrado — pedido de correção inespecífico». Publicação/v12 e confidencialidade pública permanecem aceites. Não criar outro ciclo de revisão nem reabrir o anúncio para preencher a lacuna. Apresentar à Tempo na consolidação para aceitar a limitação ou solicitar ensaio complementar delimitado; nenhum desses desfechos é presumido. Entrada dashboard conserva a classificação anterior, sem impedir o avanço para trecho independente.
Linha 08 — interesse empresarial: no anúncio QA B7 de três papéis, observar empresa, país da entidade e origem, depois recibo/recuperação, filtros/denominador e repetição idempotente. Não repetir o workflow da linha 07. Evidência: `line07-evidence-limitation-decision-20261015.json`; comparação: `line07-note-comparison-20261015.json`. Demais confirmações preservadas.
<!-- 20261015_line07_notes_compared -->
## Linha 07 — pedido e nota de ressubmissão comparados por leitura
Comparação READ ONLY: pedido v5 «validar as autorizações solicitadas»; nota v6 «Submissão confirmada do formulário privado por etapas». Revisões e registos de revisão coincidem; consentimento de análise na v6 não demonstra validação de autorizações. A nota é confirmação de envio e não responde substantivamente ao pedido. O pedido não discrimina quais autorizações, campo, documento ou alteração exigida; não é possível identificar uma alteração concreta em falta nem concluir que era obrigatória. Limitação documental específica: ausência de resposta identificando as autorizações e o resultado da sua conferência. Não classificar como falha funcional nem exigir alteração de campo/documento por suposição. Critério de atendimento ao pedido permanece não demonstrado. Publicado/v12 preservado; confidencialidade pública aceite permanece válida. Não repetir transições nem reabrir o anúncio.
Evidência: `line07-note-comparison-20261015.json`; consulta guardada `line07-notes-readonly-20261015.php`. Apenas leitura de dados QA, sem exportar snapshots, documentos, mandato ou contactos. Não encerra por inferência a entrada de revisão pelo dashboard, pendência distinta já registada. Demais confirmações preservadas.
<!-- 20261015_line07_consolidation -->
## Linha 07 — provas consolidadas; limite de encerramento
Consolidação: submissão v2/QA21, triagem v3 e revisão v4/QA24, pedido de informação v5/QA24, ressubmissão v6/QA21, triagem v7 e revisão v8/QA24, níveis de aprovação v9–11/QA24 e publicação v12/QA25 confirmados por transições persistidas e relatos visuais da conversa. Projeção pública sem mandato/contactos/condições internas aceite por transcrição. Independência dos três intervenientes demonstrada. Não repetir transições nem reabrir o anúncio publicado.
Linha 07 ainda parcial: comparação dos snapshots v5/v6 encontrou payload e objetos inalterados, sem revisão updated entre ambos; demonstra ressubmissão, mas não alteração corretiva efetiva. Falta identificar a resposta à correção (inclusive eventual esclarecimento na nota, a conferir sem exportar conteúdo privado). Entrada pelo dashboard de revisão também sem prova específica; tentativa atual abriu dashboard de QA21, não QA24/QA25, e não demonstra esse critério. São critérios do roteiro original, não requisitos novos. Próximo trecho: esclarecer/demonstrar o atendimento ao pedido de informação; preservar publicação/v12 e todas as confirmações aceites.
Evidências: `line07-consolidated-SQL-20261015.json`, `line07-correction-comparison-20261015.json`, `line07-triage-QA24-20261015.png`, `line07-review-QA24-20261015.png`, `line07-public-manual-confirmation-20261015.json`, `line07-public-projection-manual-20261015.json`. Leitura SQL READ ONLY guardada contra ativo; sem alteração de produto, permissões ou dados. Outras linhas preservadas.
<!-- 20261015_line07_public_projection_passed -->
## Linha 07 — projeção pública sem dados reservados confirmada
O responsável transcreveu a página pública do anúncio publicado/v12: título, modalidade, setor, montante indicativo 1000.00–1250.00 MZN, objetivo/teaser e aviso de limites. Não constam mandato, contactos ou condições internas. **Publicação e confidencialidade da projeção pública: passou**, por confirmação manual e transcrição; não inferir inspeção de HTML/API. Ciclo relatado de correção/ressubmissão/aprovação/publicação preservado, sem repetição. Evidência: `line07-public-projection-manual-20261015.json`. Não encerra automaticamente outros critérios do percurso 7 (países/estatísticas), entrada pelo dashboard ou resultados visuais individuais não discriminados. Nenhuma alteração no ativo.
<!-- 20261015_line07_public_confirmed -->
## Linha 07 — publicação visível confirmada pelo responsável
Responsável confirmou a página pública visível («esta publicada»), após receber o endereço exato. Publicação/v12 confirmada por leitura QA e observação manual. Histórico de estados relatados: pendente de informação/v5, submetido/v6, em revisão/v8, aprovação nível 1/v9, nível 2/v10, aprovado/v11 e publicado/v12. Não repetir estas transições. A ausência de mandato, contactos e condições internas na projeção pública ainda não foi confirmada expressamente; linha composta permanece parcial apenas nos critérios não demonstrados. Prova: `line07-public-manual-confirmation-20261015.json`. Registo documental, sem alteração no ativo.
<!-- 20261015_line07_review_observed -->
## Linha 07 — encaminhamento para revisão confirmado
QA24 encaminhou o mesmo anúncio para revisão: Triagem/v3 → Em revisão/v4, observado no Chrome e no histórico em 15/10/2026 às12:49:12, Moçambique. Submissão v2 e triagem v3 preservadas. Próximo passo do roteiro: fundamentar e Pedir informação. Pedido de correção, correção/ressubmissão, aprovação e publicação continuam por observar. Provas: `line07-review-QA24-20261015.json` e `line07-review-QA24-20261015.png`. Clique único autenticado, sem alterar código, permissões ou ativo. Linha composta permanece parcial.
<!-- 20261015_line07_triage_blocked -->
## Linha 07 — triagem bloqueada; diagnóstico focal QA
**Atualização após diagnóstico e clique autenticado:** Bloqueio de triagem registado e resolvido em QA: faltava nota com 10 caracteres (condição técnica existente). QA24 tinha papel/âmbito corretos; nenhuma atribuição individual exigida. Explicação visível e acessível instalada; TypeScript e build passaram, condições disabled e servidor intactos. Clique único de QA24 em Iniciar triagem: submitted/v2 → triage/v3 em 15/10/2026 às12:43:40, Moçambique. Submissão QA21/v2 preservada no histórico. Correção, aprovação e publicação por observar. Próximo: no mesmo anúncio, preencher nota e Encaminhar para revisão; não repetir submissão nem triagem. Provas: `line07-triage-after-readonly-20261015.json`, `line07-triage-QA24-20261015.png`, `line07-triage-feedback-QA-20261015.json`. Apenas transição de triagem na QA; nenhuma mudança de papéis, dados privados do anúncio ou ativo.
Observado no Chrome autenticado como QA24: anúncio antigo `172aa874-98fc-4bf6-b78f-d2e9a386d345`, **Submetido/v2**, botão «Iniciar triagem» desativado e «Motivo da alteração ou nota para a revisão» vazio. Etapa registada **bloqueada**; correção, aprovação e publicação **por observar**. A submissão de QA21 permanece aceite; não recriar nem ressubmeter.
Causa da interface: `busy || note.trim().length < 10`; o servidor já exige nota `min:10`. Falta preencher a nota no mesmo anúncio, imediatamente acima do botão. Mínimo de caracteres é escolha técnica existente, não decisão organizacional da Tempo. A QA recebe explicação acessível junto às ações, conservando a condição e as autorizações.
Leitura isolada READ ONLY (`line07-triage-readonly-20261015.json`) confirma QA24 Validador ativo, âmbito global incluindo `business_sale`, acesso operacional e independência do titular QA21. Não há atribuição individual do anúncio exigida pela policy. MFA recente da sessão real continua necessário; os falsos negativos do preflight CLI anterior ocorreram sem essa sessão e não provam falta de papel. O botão servido na sessão QA24 demonstra `canTriage=true` nessa resposta, não dispensa a verificação do servidor no clique.
Comparação: provas `option-B7-business-policy-QA.json`, `option-B7-three-actor-HTTP.json`, `option-B7-three-actor-SQL.json` e decisão `option-B7-legacy-approval-decision.md`. A QA já usa Promotor → Validador → Publicador; não exige administração universal, quarto interveniente ou segundo Validador. Mesmo Validador pode concluir os dois níveis legados; Publicador permanece distinto dos aprovadores. Confidencialidade, versão e histórico preservados. Origem organizacional: funções aprovadas pela Tempo, consolidadas em AGENTS.md; âmbito técnico documentado em B7/C143. Vinculado a AUD-BIZ-01/AUD-OP-03/AUD-OP-04 na linha 07 existente.
<!-- 20261015_line07_submission_persisted -->
## Linha 07 — submissão QA21 confirmada por persistência
Leitura SQL READ ONLY em 15/10/2026 confirmou o anúncio preparado `172aa874-98fc-4bf6-b78f-d2e9a386d345` em **submitted/v2**, titular QA21. A transição **draft → submitted**, autor21, foi registada em **15/10 às09:47:18UTC / 11:47:18 em Moçambique**. O responsável tinha relatado que o botão passou a funcionar; a resposta seguinte reproduziu o pedido de mensagem/estado, sem fornecer esse resultado visual. A leitura demonstra a submissão persistida e não uma nova ação do agente. Não repetir submissão, voltar ao rascunho ou refazer confirmações já aceites.
Evidência: `outputs/investmoz-audit-current-20261012/line07-status-after-button-working-readonly-20261015.json`; metadados em `acceptance-396c-results.json`, linha 07, `latest_submission_persistence_confirmation`. O feedback visual após o envio não foi transcrito nem observado pelo agente e não é inferido pela transição. Linha composta mantém-se parcial; fases de revisão/correção/ressubmissão/aprovação/publicação e confirmação de teaser conservam o âmbito original. Sem novos pedidos HTTP de submissão, alterações em código, dados, permissões, MFA ou ativo; leitura isolada e guardada, provas anteriores preservadas.
<!-- 20261015_line07_button_working -->
## Linha 07 — botão a funcionar segundo confirmação manual
Em 15/10/2026, o responsável informou «agora esta a funcionar», no contexto do botão **Confirmar e submeter para análise** do anúncio preparado. Registada a recuperação funcional relatada do botão. Não exigir repetição do bloqueio nem captura retrospetiva da condição em falta. A causa concreta e a leitura visual da lista de condições não foram identificadas; não atribuir o resultado a uma condição específica ou afirmar que o agente observou o Chrome.
A mensagem não declara se o botão já foi acionado nem o resultado da submissão. Fase QA21/linha 07 continua pendente desse resultado; não repetir uma submissão eventualmente já executada. Metadados em `acceptance-396c-results.json`, linha 07, `latest_submission_button_observation.manual_followup`. Sem novos ensaios, compilação, alterações em código, dados, permissões, MFA ou ativo neste registo; correção focal QA anterior e demais provas preservadas.
<!-- 20261015_line07_disabled_feedback -->
## Linha 07 — botão de submissão indisponível; motivo agora explicado na QA
O responsável relatou que **Confirmar e submeter para análise** permanece indisponível depois de introduzir o código; confirmou depois a caixa assinalada e ausência de «Versão 1» no campo. Não atribuir o bloqueio a erro de digitação, consentimento ou MFA sem observação da condição efetiva. O inventário do conector atual retornou zero apps e zero navegadores: a página do Chrome local não foi observada nem manipulada pelo agente. A confirmação de draft/v1 e campos obrigatórios válidos em `line07-draft-readonly-20261015.json` não demonstra os valores voláteis da página.
Correção focal **exclusivamente na fonte e bundle QA**: `resources/js/pages/investment/business-wizard.tsx` passa a mostrar a lista das condições em falta junto ao código e botão (gravação, caixa de análise interna, código completo incluindo eventual espaço nas extremidades, ou cada uma das três declarações). A lista tem região de estado e associação acessível ao campo/botão. A condição original `disabled` foi comparada e preservada integralmente; comparação do código, função de submissão, validação e autorização do servidor não foram flexibilizadas. **Origem: escolha técnica de apresentação/feedback para uma dificuldade observada, não nova exigência organizacional da Tempo.** Vinculada aos requisitos AUD-BIZ-01/AUD-OP-03/AUD-OP-04 da linha 07 existente, sem nova matriz, ID ou critério.
TypeScript e compilação QA passaram. Manifesto QA trocado após preparação, com fontes/manifesto anteriores guardados e chunks antigos preservados. Fonte/bundle da raiz, matriz e backlog priorizado mantêm hashes. Uma primeira tentativa de trocar o manifesto rejeitou o caminho de backup vazio, mantendo o antigo selecionado; o recibo dessa tentativa foi corrigido para **não instalado** e preservado, e a troca concluída com backup explícito na QA. Não houve alteração da política de execução do Windows. Evidência final: `outputs/investmoz-audit-current-20261012/line07-submit-feedback-QA-20261015.json`; fonte para revisão `line07-submit-feedback-QA-business-wizard-20261015.tsx`; reversão indicada no recibo.
Próximo: responsável recarrega a página QA para obter o novo bundle, preenche novamente apenas as confirmações temporárias e comunica a indicação **Para disponibilizar o botão de submissão** que persistir. Não presumir causa resolvida nem submissão executada pela compilação. Fase QA21/linha composta e fases posteriores continuam pendentes, sem novo ensaio de aceitação, credenciais/MFA lidos, alterações em dados, permissões, serviços ou ativo. Provas anteriores preservadas; candidata final e ativação separadas.
<!-- 20261015_line07_draft_observed -->
## Linha 07 — anúncio preparado identificado; submissão por observar
Em 15/10/2026, o responsável transcreveu a página **Preparar oportunidade de negócio**, etapa 8/8, referência `MNE-0a29f02d-6352-4e15-9923-781945afae4d`, versão 1, informação sintética, três declarações yes, mensagem **Rascunho guardado no servidor** e botão **Confirmar e submeter para análise**. Esta é observação manual de apresentação, não confirmação de submissão. A leitura SQL READ ONLY na QA `stability_consumers_20261011_084534_test:55441` confirmou correspondência ao anúncio existente `172aa874-98fc-4bf6-b78f-d2e9a386d345`, draft/v1, titular QA21 com autorização de atualização; wizard v2, validação dos campos de submissão sem pendências, setor presente e nenhuma transição registada. Não confundir a referência MNE com outro registo nem com um segredo MFA.
Próximo passo já previsto na fase QA21: na etapa 8/8, assinalar a confirmação de exatidão/análise interna, introduzir o código MNE mostrado no topo da própria página e clicar uma vez em **Confirmar e submeter para análise**. Recolher mensagem/estado após a ação. O código é confirmação do anúncio existente; não pedir código MFA, criar outro rascunho ou editar os dados preparados. Submissão não é publicação. A fase QA21 da linha 07 continua não observada integralmente até o resultado dessa ação; fases posteriores e lista fixa preservadas.
Evidência: `outputs/investmoz-audit-current-20261012/line07-draft-readonly-20261015.json`; metadados da observação em `acceptance-396c-results.json`, linha 07. Diagnóstico sem pedidos HTTP de submissão, credenciais/sessões lidas ou alterações em código, dados, permissões, MFA e ativo. Nenhum novo critério ou fecho agregado.
<!-- 20261015_line06_Office_passed -->
## Linha 06 — DOCX e XLSX descarregados e abertos
Em 15/10/2026, o responsável respondeu «aparecem sim, e consigo abrir» à pergunta expressa sobre DOCX/XLSX nas Transferências do Chrome, obtidos por **Consultar original autorizado**. Registado **passou no download e abertura dos dois formatos Office** da Franquia 56. Não exigir pré-visualização dentro do portal nem repetir os downloads/aberturas. Nomes individuais e conteúdo dos ficheiros não foram retranscritos; não inferir edição, validade real ou compatibilidade com outros programas.
Relato preservado em `acceptance-396c-results.json`, linha 06, `latest_manual_Office_confirmation`. As confirmações anteriores de apresentação/recuperação da ficha, licença PDF descarregada/visualizada e aparência verde das amostras ficam preservadas. Não encerrar silenciosamente os formatos individuais de imagem nem fases QA24/QA25 e QA23 ainda pendentes; linha composta continua parcial. Apenas documentação, sem novos ensaios ou alterações em produto, dados, permissões, MFA e ativo; demais estados preservados.
<!-- 20261015_line06_ficha_recovered -->
## Linha 06 — informação da ficha apresentada e recuperada
Em 15/10/2026, o responsável confirmou «na fichas toda a informaçã esta presente e reabre com a informação», após a orientação relativa à ficha da Franquia 56. Registado **passou na apresentação e recuperação da informação da ficha ao reabrir**, incluindo os valores apresentados no contexto orientado. Não repetir essa conferência. Não inferir edição/gravação, troca de país/pai com limpeza de descendentes, nova sessão autenticada ou download de ficheiros a partir da recuperação da ficha.
Relato preservado em `acceptance-396c-results.json`, linha 06, `latest_manual_ficha_recovery_confirmation`. Mantêm-se as provas anteriores de existência dos dados, download/visualização da licença PDF e esclarecimento das imagens sintéticas verdes. Downloads DOCX/XLSX ainda não confirmados expressamente; identificação individual JPEG/WebP não extrapolada do aspeto verde. Linha composta e fases QA24/QA25 e QA23 continuam pendentes. Apenas documentação, sem novos ensaios ou alterações em produto, dados, permissões, MFA e ativo; restantes resultados preservados.
<!-- 20261015_line06_documents_visible -->
## Linha 06 — documentos visualizados; fundo verde das amostras esclarecido
Em 15/10/2026, o responsável informou «os documento visualiza, mas as fotos so parece o fundo verde sem conteudo. se esta correcto assim, entao esta tudo bem», após confirmar o download da licença PDF e receber orientação para a abrir. Registada a visualização documental, incluindo a licença PDF no contexto imediatamente anterior. A aceitação da aparência das imagens foi condicionada à correspondência com a amostra QA; o gerador `consumer-lot-file-QA.php` e a inspeção visual local já realizada mostram fundo verde com texto branco pequeno. `prepare-B8-fixtures.py` cria também o JPEG com fundo verde e texto de simulação, sem pessoas ou local real. Esse aspeto é o conteúdo preparado e não demonstra falha por si só. Não inferir observação do texto pequeno, correspondência individual de cada derivada ou formatos que não foram identificados.
Não repetir o download/visualização já confirmados nem classificar a dificuldade inicial como falha geral persistente de todos os documentos. Os nomes e formatos adicionais não foram discriminados; downloads DOCX/XLSX, identificação JPEG/WebP, seletores/hierarquia e recuperação da ficha continuam sem confirmação específica. A linha 06 mantém resultado parcial, bem como fases QA24/QA25 e QA23 pendentes. Registo em `acceptance-396c-results.json`, linha 06, `latest_manual_resources_confirmation`, preservando relatos anteriores como histórico. Apenas documentação, sem novos ensaios ou alterações em produto, dados, permissões, MFA e ativo; resultados prévios preservados.
<!-- 20261015_line06_PDF_download -->
## Linha 06 — download da licença PDF confirmado manualmente
Em 15/10/2026, o responsável respondeu «aparece sim» à pergunta se o PDF da licença aparece nas Transferências do Chrome após o link direto de download. Registado **passou apenas no download do PDF `qa-B8-franchise-license.pdf`**, recurso `21dae751-99da-44a7-bbca-adb841982cdc` da Franquia 56. O ficheiro e URL são os indicados no contexto imediatamente anterior, não novamente transcritos pelo responsável. Não inferir abertura/legibilidade do PDF, resultados dos outros ficheiros ou resolução geral do relato anterior de que todos não abriam. Não repetir o download confirmado.
Relato preservado em `acceptance-396c-results.json`, linha 06, `latest_manual_PDF_download_confirmation`. A linha 06 continua parcial, com abertura/legibilidade, restantes formatos, seletores/hierarquia e recuperação ainda pendentes; fases QA24/QA25 e QA23 inalteradas. Apenas documentação, sem novos ensaios ou alterações em produto, dados, permissões, MFA e ativo; resultados anteriores preservados.
<!-- 20261015_line06_resources_report -->
## Linha 06 — recursos listados; abertura dos ficheiros por esclarecer
O responsável relatou «em relação aos recursos ele mostra, mas a imagem não é visivel só um fundo ver, os documentos não abre» e esclareceu «todos». Registada dificuldade de consulta dos recursos da Franquia 56, sem converter a listagem em prova de abertura/download. A confirmação anterior da existência dos dados permanece válida. A leitura SQL READ ONLY na QA `stability_consumers_20261011_084534_test:55441` encontrou QA21 com leitura autorizada e sete originais ativos, scan clean, bytes presentes, MIME detetado e hashes de conteúdo/scan correspondentes; três derivadas WebP também presentes e íntegras. Não foram realizados pedidos HTTP autenticados nem demonstrados downloads atuais. Nenhuma recusa de recursos foi encontrada na auditoria consultada de 15/10; isso não prova que o clique tenha ocorrido nem exclui erro no navegador.
O código e a inspeção visual local do exemplar `qa-consumer-original-20261012.png` mostram que a imagem sintética tem fundo verde e texto branco pequeno no canto superior esquerdo. Esse aspeto, por si só, não demonstra falha de renderização. A amostra JPEG de B8 também foi criada com fundo verde. A imagem/WebP efetivamente vista pelo responsável ainda não foi identificada. O diagnóstico CLI registou `read_error_type=Error` nas imagens porque GD não está carregado nesse CLI, não como evidência de ficheiro danificado; os hashes e MIME foram conferidos antes dessa tentativa de descodificação. Nenhuma extensão ou serviço foi alterado.
Na interface, **Ver recurso** seleciona metadados; **Consultar original autorizado** solicita os bytes, com `Content-Disposition: attachment`, pelo que pode descarregar em vez de abrir no separador. DOCX/XLSX têm como critério o download original, sem nova exigência de pré-visualização Office. Próximo esclarecimento focal: licença `qa-B8-franchise-license.pdf`, recurso `21dae751-99da-44a7-bbca-adb841982cdc`, através do link de download já existente; distinguir descarga, erro ou página vazia. Não repetir Workflow, uploads ou scan. Evidência: `outputs/investmoz-audit-current-20261012/case56-resources-readonly-20261015.json`; referências de preparação `consumer-lot-file-QA.php` e `prepare-B8-fixtures.py`. Linha 06 parcial; restantes partes e estados preservados. Sem alterações em produto, dados, permissões, MFA e ativo.
<!-- 20261015_line06_partial -->
## Linha 06 — existência dos dados confirmada; ficheiros e recuperação pendentes
Em 15/10/2026, o responsável informou «confirmo a existencia dos dados», em resposta à orientação de consulta da Franquia 56. Preservada a confirmação parcial da existência dos dados da ficha no contexto de `/minhas-oportunidades/56/view`. Não inferir a abertura/legibilidade de JPEG/PDF, visualização WebP, downloads DOCX/XLSX, recuperação ao reabrir ou o comportamento dos seletores/hierarquia a partir da existência dos dados. Não repetir a conferência da existência já confirmada.
Relato guardado em `acceptance-396c-results.json`, linha 06, `latest_partial_confirmation`. A fase QA21 e a linha composta continuam não observadas integralmente, com resultado parcial preservado; fases QA24/QA25 e QA23 mantêm-se pendentes. Apenas documentação, sem novos ensaios ou alterações em produto, dados, permissões, MFA e ativo; confirmações anteriores e estados agregados preservados.
<!-- 20261015_line05_QA21_passed -->
## Linha 05 — QA21: seis obrigações apresentadas e recuperadas
Em 15/10/2026, após a pergunta sobre os campos da página e a sua apresentação ao fechar/reabrir a Parceria 34, o responsável respondeu «revi e estao todos apresentados sem omissões». Registado **passou na parte QA21 de consulta e recuperação das seis obrigações**, no contexto orientado de `/minhas-oportunidades/34/view`. A confirmação complementa o relato anterior da presença no documento; não repetir os pontos confirmados. É confirmação manual contextual, sem nova captura automática, URL retranscrito ou detalhe do modo de reabertura. Não inferir nova gravação/edição, submissão, pareceres, aprovação ou disponibilização.
Evidência: `outputs/investmoz-audit-current-20261012/acceptance-396c-line05-QA21-manual-confirmation-20261015.json`, refletida na observação da fase 1 da linha 05 em `acceptance-396c-results.json`; relato parcial anterior preservado como histórico. Fase 2/QA24→QA25 e linha composta continuam pendentes. Apenas registo documental; sem novos ensaios ou alterações em produto, dados, permissões, MFA e ativo. Restantes linhas, matriz, critérios e estados agregados preservados.
<!-- 20261015_line05_partial -->
## Linha 05 — presença das seis obrigações relatada; recuperação pendente
Em 15/10/2026, o responsável informou «verificado e todas as as seis obrigaçoes constam no documento», em resposta à conferência da Parceria 34. Preservada a confirmação parcial da presença das seis obrigações (laborais, calendário, gestão, matérias reservadas, saída e impasse) no documento referido. A palavra «documento» não permite distinguir ainda a ficha do portal de um ficheiro anexo. Não inferir a recuperação dos campos ao reabrir, que não foi explicitamente confirmada. Não repetir a verificação já declarada; pedir apenas a identificação da apresentação consultada e a recuperação ainda pendente.
Orientação de consulta: `/minhas-oportunidades/34/view`, sem acionar Workflow. A fase QA21 e a linha composta permanecem não observadas integralmente, com resultado parcial preservado em `acceptance-396c-results.json`, linha 05, `latest_partial_confirmation`. Fase QA24/QA25 não observada; nenhum fecho agregado. Sem novos ensaios ou alterações em código, dados, permissões, MFA e ativo; linhas 01/QA21, 03 e 04 e demais estados preservados.
<!-- 20261015_line04_passed -->
## Linha 04 — mapa público e carteira: passou por confirmação manual
Em 15/10/2026, o responsável respondeu «verifiquei e esta tudo conforme» à conferência da linha 04: mapa público em janela sem sessão (filtros, legenda e ausência de coordenadas privadas) e corredor da carteira na sessão QA21 (relações ou indicação explícita de ausência). Registado **linha 04: passou** no âmbito indicado. URLs, modo de sessão e pontos conferidos são os do contexto imediatamente anterior, não foram novamente descritos na confirmação. Não inferir quais relações concretas foram apresentadas, dados cartográficos novos, alterações de publicação ou novos direitos de acesso.
Evidência: `outputs/investmoz-audit-current-20261012/acceptance-396c-line04-manual-confirmation-20261015.json`, refletida na linha 04 de `acceptance-396c-results.json`. Linhas 03 e 04 confirmadas; não repetir. O registo não altera por si o fecho agregado do percurso 4, da opção B ou da ativação. Linha 01/QA21 passou e fase QA24/QA25 pendente preservadas. Apenas documentação, sem novos ensaios ou alterações em produto, dados, permissões, MFA e ativo; matriz, critérios e restantes estados preservados.
<!-- 20261015_QA21_line03_passed -->
## Linha 03 — QA21: passou por confirmação manual
Em 15/10/2026, o responsável respondeu «verifiquei esta conforem» à conferência dos cinco pontos do Negócio 33: mandato, histórico, teaser, divulgação e distinção entre promotor real e operadora. Registado **linha 03/fase 1/QA21: passou**. A rota `/minhas-oportunidades/33/view` é a indicada no contexto, não novamente transcrita nesta confirmação. A mensagem anterior do Workflow e o 403 de `/edit` mantêm-se históricos; esta confirmação demonstra a consulta dos cinco pontos, sem atribuir uma transição específica, edição, nova submissão, aprovação ou publicação.
Evidência: `outputs/investmoz-audit-current-20261012/acceptance-396c-line03-QA21-manual-confirmation-20261015.json`, refletida na linha 03 de `acceptance-396c-results.json`. Não repetir os pontos confirmados. Linha 04/mapa e carteira continua pendente; o percurso 4 não é integralmente encerrado. Linha 01/QA21 passou preservado, fase QA24/QA25 da linha 01 pendente. Apenas registo documental: sem novos ensaios ou alterações em produto, dados, permissões, MFA e ativo; restantes linhas, critérios, matriz e estados agregados preservados.
<!-- 20261015_QA21_case33_access -->
## Linha 03 — Negócio 33: consultar sem repetir o workflow
O responsável relatou a mensagem «Ação interna registada; não representa decisão externa.» no Workflow de `/minhas-oportunidades/33/view`, sem identificar a transição concreta. Posteriormente confirmou 403 como QA21 em `/minhas-oportunidades/33/edit`. A leitura SQL READ ONLY na QA `stability_consumers_20261011_084534_test:55441` confirmou submetido/v67, titular QA21, âmbito/representação válidos, `canView=true` e `canEdit=false`; a auditoria identifica QA21 nas recusas de edição de 15/10. Não atribuir a submissão atual ao botão relatado sem correlação específica.
A recusa de edição decorre do estado submetido na política existente. O link `/edit` do roteiro era uma escolha de implementação inadequada à conferência de leitura, não exigência organizacional da Tempo. Corrigido para `https://portal-investidor.test:18445/minhas-oportunidades/33/view`. Conferir mandato, histórico, teaser, divulgação e distinção entre promotor real e operadora, sem nova ação de Workflow, alteração de estado ou permissões. **Linha 03 continua não observada nos critérios de aceitação**: a mensagem e a recusa não confirmam esses cinco pontos. Linha 01/QA21 passou e restantes provas preservadas. Evidência: `outputs/investmoz-audit-current-20261012/case33-access-readonly-20261015.json`. Sem novos ensaios autenticados, leitura de credenciais/sessões ou alterações em código, dados, MFA e ativo.
<!-- 20261015_QA21_line01_passed -->
## Linha 01 — parte QA21 confirmada manualmente
Em 15/10/2026, o responsável confirmou na conversa: «01 — QA21: passou. Campos da licença conferidos e documento aberto e legível.» Registado **passou somente na fase 1/QA21 da linha 01**: campos da licença do Projeto 30 e abertura/legibilidade do documento. As rotas `/minhas-oportunidades/30/view` e `/minhas-oportunidades/30/resources` são as orientadas no contexto, não foram novamente transcritas na confirmação. Não inferir outros documentos, gravação, recuperação noutra sessão, alterações de licenciamento, pareceres, aprovação ou publicação.
A fase 2/QA24→QA25 mantém-se não observada e a linha composta permanece pendente, com o resultado positivo de QA21 preservado sem repetição. O 403 anterior de edição e o bloqueio automático C135 permanecem históricos; não invalidam a consulta manual confirmada. Evidência: `outputs/investmoz-audit-current-20261012/acceptance-396c-line01-QA21-manual-confirmation-20261015.json`, refletida na parte correspondente de `acceptance-396c-results.json`. Apenas registo documental, sem novos ensaios ou alterações em código, dados, permissões, MFA e ativo; restantes linhas, matriz, critérios e estados agregados preservados.
<!-- 20261015_QA21_case30_access -->
## QA21 — Projeto 30: entrada de consulta corrigida
O responsável observou 403 em `/minhas-oportunidades/30/edit`, após o MFA, e abertura direta do dashboard sem novo pedido de autenticação. A leitura SQL READ ONLY na QA `stability_consumers_20261011_084534_test:55441` confirmou o Projeto 30 submetido/v54, titular QA21, `canView=true` e `canEdit=false`. A auditoria identifica QA21 nas recusas de edição de 15/10/2026. A origem da recusa é a verificação existente de estado em `PortalProfileAccess::canEdit`, não uma rejeição demonstrada do código MFA.
Correção da orientação da linha 01: abrir `https://portal-investidor.test:18445/minhas-oportunidades/30/view` para conferir os campos e `/minhas-oportunidades/30/resources` para abrir a licença existente. A escolha de `/edit` no roteiro era uma opção de implementação inadequada ao estado atual; não constitui exigência organizacional da Tempo. Não reabrir o estado nem repetir submissão para permitir a consulta. As transições posteriores mantêm o âmbito original. A consulta corrigida e a legibilidade documental continuam não observadas; o 403 de edição fica registado sem marcar a linha inteira como falha ou aprovada.
Evidência: `outputs/investmoz-audit-current-20261012/case30-access-readonly-20261015.json`. Sem leitura de credenciais/sessões, ensaios autenticados automáticos ou alterações em código, dados, permissões, MFA e ativo. Lista/matriz/critérios existentes e restantes estados preservados.
<!-- 20261014_QA21_browser_block -->
## Passagem QA21 — impedimento antes da interface
@@ -1871,3 +2236,12 @@ C129 corrigido em QA no cadastro existente: contacto do promotor a partir do ras
Atualização 10:26 de Moçambique: responsável confirmou a entrega dos emails; leitura ativa recuperou contacto verificado e MFA configurado/confirmado para Aurora 14, Palmira 15 e Mario 16. Não repetir estes critérios pessoais. Restam cadastro autenticado da Tempo Lda e atribuições internas dos papéis/âmbitos já designados; leitura atual confirma zero organizações e zero atribuições. Novo login observado, atribuições e abertura operacional são provas distintas. Atualização documental, sem alterações ativas; COUNTRY02/A/B/C37 preservados. Procedimento atualizado: `outputs/investmoz-staff-preparation-20261012/procedimento-validacao.md`.
Por instrução do responsável, a demonstração preparada foi substituída pelo registo pendente das três pessoas designadas. No destino: Aurora ID 14 (`aurora.chachuaio@tempo.co.mz`), Palmira ID 15 (`palmira.matsinhe@tempo.co.mz`) e Mario ID 16 (`mario.melembe@tempo.co.mz`). Designações anteriores preservadas, sem atribuição automática de papéis. Faltam definição pessoal da palavra-passe, confirmação efetiva do contacto, configuração/confirmação do MFA, cadastro autenticado da organização operadora e atribuição autenticada dos âmbitos já decididos. Não exigir comprovativos de promotor externo para Aurora. COUNTRY02 ON; workflow OFF; A/B e C37 não reabertos. Provas: `outputs/investmoz-staff-preparation-20261012/resultado.md`, `result.json`, `qa-result.json`, `active-access.json`. Estes registos não encerram os requisitos de operação ou workflow da matriz existente.
## 15/10/2026 — disponibilização B autorizada e concluída
A Tempo autorizou `B-final-fabf722bc8c6` com C137 e as limitações documentadas. Entrega concluída no destino ativo: 36 fontes e compilação verificadas; apenas `2026_10_09_190000_prepare_investor_path` instalada pela ação autenticada de Osmane Nala às 15:27:09 UTC. `INVESTOR_PATH_ENABLED=true` habilitado às 15:28:01 UTC após verificação. Manutenção encerrada; `/investimentos` aberto na sessão real, sem criar dossier.
Backup/restauro fresco às 15:09:24 UTC: 295 tabelas, 31 sequências e 815 ficheiros. Comparação posterior por leitura confirma os dados de negócio anteriores preservados; acréscimos esperados: migration, definição e auditoria; variações técnicas de sessão/cache. COUNTRY02, demais configurações, serviços e DevTools preservados. Os 12 critérios aceites não foram repetidos. Mantêm-se as limitações aceites: linha 07 documental; C137 sem aceitação visual específica; estado intermédio sustentado por código/provas anteriores.
Resultado e recibo: `outputs/investmoz-audit-current-20261012/B-ativacao-concluida-20261015/`. ZIP das provas SHA-256 `bacefba6d72c3f36d8630ffc02e58f02fded3e71a44e71d4cddd6fc1a799cf83`. Candidata e suplemento imutáveis novamente verificados. Reversão conforme procedimento aprovado, preservando dados posteriores. Esta nota atualiza somente esta entrega; as restantes pendências da matriz mantêm-se.
@@ -0,0 +1,150 @@
{
"at": "2026-10-15T15:21:47+00:00",
"target": "investemoz:5432",
"SQL_read_only": true,
"accounts": [
{
"account_id": 1,
"manager_designated": false,
"email_verified": true,
"MFA_enrolled": false,
"MFA_confirmed": false
},
{
"account_id": 2,
"manager_designated": true,
"email_verified": true,
"MFA_enrolled": true,
"MFA_confirmed": true,
"decrypts_current_runtime_key": true,
"raw_is_Base32": false,
"raw_has_serialized_string_prefix": true
},
{
"account_id": 3,
"manager_designated": false,
"email_verified": false,
"MFA_enrolled": false,
"MFA_confirmed": false
},
{
"account_id": 4,
"manager_designated": false,
"email_verified": false,
"MFA_enrolled": false,
"MFA_confirmed": false
},
{
"account_id": 5,
"manager_designated": false,
"email_verified": false,
"MFA_enrolled": false,
"MFA_confirmed": false
},
{
"account_id": 6,
"manager_designated": false,
"email_verified": false,
"MFA_enrolled": false,
"MFA_confirmed": false
},
{
"account_id": 7,
"manager_designated": false,
"email_verified": false,
"MFA_enrolled": false,
"MFA_confirmed": false
},
{
"account_id": 8,
"manager_designated": false,
"email_verified": false,
"MFA_enrolled": false,
"MFA_confirmed": false
},
{
"account_id": 9,
"manager_designated": false,
"email_verified": false,
"MFA_enrolled": false,
"MFA_confirmed": false
},
{
"account_id": 10,
"manager_designated": false,
"email_verified": false,
"MFA_enrolled": false,
"MFA_confirmed": false
},
{
"account_id": 11,
"manager_designated": false,
"email_verified": false,
"MFA_enrolled": false,
"MFA_confirmed": false
},
{
"account_id": 12,
"manager_designated": false,
"email_verified": false,
"MFA_enrolled": false,
"MFA_confirmed": false
},
{
"account_id": 13,
"manager_designated": true,
"email_verified": true,
"MFA_enrolled": true,
"MFA_confirmed": true,
"decrypts_current_runtime_key": true,
"raw_is_Base32": false,
"raw_has_serialized_string_prefix": true
},
{
"account_id": 14,
"manager_designated": false,
"email_verified": true,
"MFA_enrolled": true,
"MFA_confirmed": true,
"decrypts_current_runtime_key": true,
"raw_is_Base32": false,
"raw_has_serialized_string_prefix": true
},
{
"account_id": 15,
"manager_designated": false,
"email_verified": true,
"MFA_enrolled": true,
"MFA_confirmed": true,
"decrypts_current_runtime_key": true,
"raw_is_Base32": false,
"raw_has_serialized_string_prefix": true
},
{
"account_id": 16,
"manager_designated": false,
"email_verified": true,
"MFA_enrolled": true,
"MFA_confirmed": true,
"decrypts_current_runtime_key": true,
"raw_is_Base32": false,
"raw_has_serialized_string_prefix": true
},
{
"account_id": 17,
"manager_designated": false,
"email_verified": true,
"MFA_enrolled": true,
"MFA_confirmed": true,
"decrypts_current_runtime_key": true,
"raw_is_Base32": false,
"raw_has_serialized_string_prefix": true
}
],
"current_key_matches_pre_window_backup": true,
"previous_key_count": 0,
"LOG_LEVEL": "debug",
"no_plaintext_seeds_codes_or_recovery_values_in_receipt": true,
"credentials_changed": false,
"active_changes": 0
}
@@ -0,0 +1,20 @@
<?php
ini_set('zend.exception_ignore_args','1');
set_exception_handler(function(Throwable $e){fwrite(STDERR,'MFA read-only diagnostic stopped: '.$e::class.' line '.$e->getLine());exit(1);});
$root=dirname(__DIR__,2);require $root.'/vendor/autoload.php';$app=require $root.'/bootstrap/app.php';
(new Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables)->bootstrap($app);(new Illuminate\Foundation\Bootstrap\LoadConfiguration)->bootstrap($app);
$c=config('database.connections.'.config('database.default'));
if($c['driver']!=='pgsql'||$c['database']!=='investemoz'||(int)$c['port']!==5432||!in_array($c['host'],['127.0.0.1','localhost']))throw new RuntimeException('Destination guard');
$pdo=new PDO('pgsql:host='.$c['host'].';port=5432;dbname=investemoz',$c['username'],$c['password'],[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]);$pdo->exec('BEGIN READ ONLY');
try{
$key=config('app.key');if(str_starts_with($key,'base64:'))$key=base64_decode(substr($key,7),true);
$cipher=new Illuminate\Encryption\Encrypter($key,config('app.cipher'));$cipher->previousKeys(array_map(fn($v)=>str_starts_with($v,'base64:')?base64_decode(substr($v,7),true):$v,config('app.previous_keys',[])));
$rows=[];foreach($pdo->query('SELECT id,name,email,email_verified_at,two_factor_secret,two_factor_confirmed_at FROM users ORDER BY id')->fetchAll(PDO::FETCH_ASSOC)as$u){
$manager=in_array(strtolower($u['email']),config('portal.managers',[]),true);
$row=['account_id'=>$u['id'],'manager_designated'=>$manager,'email_verified'=>$u['email_verified_at']!==null,'MFA_enrolled'=>$u['two_factor_secret']!==null,'MFA_confirmed'=>$u['two_factor_confirmed_at']!==null];
if($u['two_factor_secret']!==null){try{$raw=$cipher->decrypt($u['two_factor_secret'],false);$row['decrypts_current_runtime_key']=true;$row['raw_is_Base32']=preg_match('/^[A-Z2-7]{16,}$/D',$raw)===1;$row['raw_has_serialized_string_prefix']=str_starts_with($raw,'s:');unset($raw);}catch(Throwable $e){$row['decrypts_current_runtime_key']=false;$row['exception_type']=$e::class;}}
$rows[]=$row;
}
$p=['at'=>gmdate('c'),'target'=>'investemoz:5432','SQL_read_only'=>true,'accounts'=>$rows,'current_key_matches_pre_window_backup'=>hash_file('sha256',$root.'/.env')===hash_file('sha256',json_decode(file_get_contents(__DIR__.'/B-activation-fresh-backup-20261015.json'),true)['private_directory'].'/files/.env'),'previous_key_count'=>count(config('app.previous_keys',[])),'LOG_LEVEL'=>config('logging.channels.single.level'),'no_plaintext_seeds_codes_or_recovery_values_in_receipt'=>true,'credentials_changed'=>false,'active_changes'=>0];
file_put_contents(__DIR__.'/B-MFA-diagnostic-readonly-20261015.json',json_encode($p,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_THROW_ON_ERROR));echo json_encode($p,JSON_UNESCAPED_UNICODE|JSON_THROW_ON_ERROR);
}finally{$pdo->exec('ROLLBACK');}
@@ -0,0 +1,48 @@
from pathlib import Path
import json,hashlib,subprocess,os
from datetime import datetime,timezone
R=Path(__file__).resolve().parent;ROOT=R.parents[1];sha=lambda p:hashlib.sha256(p.read_bytes()).hexdigest()
b=json.loads((R/'B-activation-fresh-backup-20261015.json').read_text(encoding='utf-8'));a=json.loads((R/'B-activation-Tempo-authorization-20261015.json').read_text(encoding='utf-8'));assert a['user_statement']=='A Tempo autoriza' and b['restore_verified']and b['files_verified']
private=Path(b['private_directory']);stage=private/'candidate-staging';mapping=json.loads((R/'B-suplemento-C137-sequencia-final-20261015/MAPA-DISPONIBILIZACAO-REVERSAO.json').read_text(encoding='utf-8'));ops=mapping['source_operations'];assert len(ops)==36
prior=json.loads((R/'B-destination-preflight-readonly-20261015.json').read_text(encoding='utf-8'))
assert not (ROOT/'storage/framework/down').exists()
for op in ops:assert sha(ROOT/op['path'])==op['before'] and sha(stage/op['path'])==op['after']
for n,h in prior['current_build_files'].items():assert sha(ROOT/'public/build'/n)==h
assert sha(ROOT/'.env')==sha(private/'files/.env')
build={p.relative_to(stage/'public/build').as_posix():p for p in (stage/'public/build').rglob('*')if p.is_file()}
for n,p in build.items():
t=ROOT/'public/build'/n
assert not t.exists()or sha(t)==sha(p)or n in ['manifest.json','fonts-manifest.json'],'Asset collision '+n
php='C:/laragon/bin/php/php-8.5.11-Win32-vs17-x64/php.exe'
def artisan(*args):subprocess.run([php,'artisan',*args],cwd=ROOT,check=True,capture_output=True)
def put(p,data):
p.parent.mkdir(parents=True,exist_ok=True)
with p.open('wb')as f:f.write(data);f.flush();os.fsync(f.fileno())
receipt={'at':datetime.now(timezone.utc).isoformat(),'candidate':a['candidate'],'C137':True,'sources':{},'added_assets':[],'path_flag_enabled':False,'maintenance_started':False,'maintenance_ended':False,'190000_installed':False,'no_QA_data_imported':True}
try:
artisan('down','--retry=60');receipt['maintenance_started']=True
assert (ROOT/'storage/framework/down').exists()
for op in ops:
n=op['path'];put(ROOT/n,(stage/n).read_bytes());assert sha(ROOT/n)==op['after'];receipt['sources'][n]=op['after']
for n,p in sorted(build.items()):
if n=='manifest.json':continue
t=ROOT/'public/build'/n
if not t.exists():receipt['added_assets'].append(n)
if not t.exists()or sha(t)!=sha(p):put(t,p.read_bytes())
assert sha(t)==sha(p)
put(ROOT/'public/build/manifest.json',(stage/'public/build/manifest.json').read_bytes())
assert sha(ROOT/'public/build/manifest.json')==sha(stage/'public/build/manifest.json')
assert sha(ROOT/'.env')==sha(private/'files/.env')
assert sha(ROOT/'config/inertia.php')==sha(private/'files/config/inertia.php')
artisan('view:clear');artisan('up');receipt['maintenance_ended']=True
assert not (ROOT/'storage/framework/down').exists()
receipt['result']='sources_and_build_delivered; path still disabled; authenticated190000 pending'
except Exception:
for op in ops:
n=op['path'];put(ROOT/n,(private/'files'/n).read_bytes())
for n in ['manifest.json','fonts-manifest.json']:
if(private/'files/public/build'/n).exists():put(ROOT/'public/build'/n,(private/'files/public/build'/n).read_bytes())
artisan('view:clear');artisan('up');receipt['result']='file_switch_reverted_before_installation';receipt['maintenance_ended']=True
(R/'B-activation-file-switch-20261015.json').write_text(json.dumps(receipt,indent=2)+'\n');raise
(R/'B-activation-file-switch-20261015.json').write_text(json.dumps(receipt,indent=2)+'\n')
print(json.dumps({'result':receipt['result'],'sources':len(receipt['sources']),'added_assets':len(receipt['added_assets']),'maintenance_ended':True,'flag_unchanged':True}))
@@ -0,0 +1,16 @@
{
"date": "2026-10-15",
"authority": "Tempo, Lda — instrução expressa do responsável na conversa",
"user_statement": "A Tempo autoriza",
"context": "Autoriza a proposta imediatamente anterior e os quatro pontos nela reunidos.",
"candidate": "B-final-fabf722bc8c6",
"candidate_SHA256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"supplement_SHA256": "182fb269536aa7bd84b8694ec54d1b39bf5b072abe91d0f4b1284389755fc620",
"C137_inclusion_and_documented_limitations_accepted": true,
"install_only_190000_if_absent_via_existing_authenticated_action": true,
"enable_INVESTOR_PATH_ENABLED_only_after_verification": true,
"fresh_destination_backup_restore_and_reversal_required": true,
"preserve_COUNTRY02_services_and_data": true,
"repeat_12_accepted_criteria": false,
"other_changes_authorized": false
}
@@ -0,0 +1,7 @@
<?php
ini_set('zend.exception_ignore_args','1');putenv('STABILITY_QA_MODE=consumers');
$root=dirname(__DIR__,2);$app=require $root.'/storage/app/private/investmoz-v2/portal-audit/portal-stability-source-20261011_083742/tools/portal-stability-runtime.php';
$db=Illuminate\Support\Facades\DB::connection();$target=(array)$db->selectOne('SELECT current_database() AS database,inet_server_port() AS port');
if($target!==['database'=>'stability_consumers_20261011_084534_test','port'=>55441])throw new RuntimeException('QA guard');
$db->beginTransaction();$db->statement('SET TRANSACTION READ ONLY');
try{$code=app(App\Services\VirtualDeskInstallation::class)->fingerprint();$p=['at'=>gmdate('c'),'expected_QA_fingerprint'=>$code,'target'=>$target,'method'=>'Existing installer fingerprint; no functional test or active write','active_changes'=>0];file_put_contents(__DIR__.'/B-activation-expected-fingerprint-20261015.json',json_encode($p,JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));echo json_encode($p);}finally{$db->rollBack();}
@@ -0,0 +1,23 @@
{
"date": "2026-10-15",
"Tempo_authorization_recorded": true,
"candidate": "B-final-fabf722bc8c6",
"C137_supplement_authorized": true,
"documented_limitations_accepted": true,
"destination_backup_restore_verified": true,
"backup_tables": 295,
"backup_sequences": 31,
"backup_files": 815,
"source36_and_build_staged": true,
"destination_maintenance_started": false,
"source_or_build_switched": false,
"190000_installed_by_this_task": false,
"INVESTOR_PATH_ENABLED_changed": false,
"pending": "Identificar o navegador/perfil em que o login real foi concluído; a aba conectada continua sem sessão ativa. Nenhuma nova autorização pedida.",
"authorization_to_be_requested_again": false,
"functional_criteria_repeated": false,
"active_business_or_product_changes": 0,
"login_completion_reported_by_user": true,
"observed_installer_url": "https://portal-investidor.test/management/balcao-install",
"observed_redirect": "https://portal-investidor.test/login"
}
@@ -0,0 +1,47 @@
{
"at": "2026-10-15T15:28:53+00:00",
"method": "Read-only repeatable snapshot vs verified preactivation restore; new nullable columns projected out for preexisting journeys.",
"SQL_read_only": true,
"tables_checked": 295,
"tables_exactly_equal": 289,
"differences": {
"\"public\".\"audit_events\"": {
"before": 175,
"after": 176,
"prior_rows_changed_or_removed": 0,
"new_or_changed_rows": 1
},
"\"public\".\"cache\"": {
"before": 94,
"after": 95,
"prior_rows_changed_or_removed": 4,
"new_or_changed_rows": 5
},
"\"public\".\"investor_journeys\"": {
"before": 1,
"after": 1,
"prior_rows_changed_or_removed": 0,
"new_or_changed_rows": 0
},
"\"public\".\"migrations\"": {
"before": 82,
"after": 83,
"prior_rows_changed_or_removed": 0,
"new_or_changed_rows": 1
},
"\"public\".\"questionnaire_versions\"": {
"before": 1,
"after": 2,
"prior_rows_changed_or_removed": 0,
"new_or_changed_rows": 1
},
"\"public\".\"sessions\"": {
"before": 6,
"after": 6,
"prior_rows_changed_or_removed": 1,
"new_or_changed_rows": 1
}
},
"all_prior_business_rows_preserved": true,
"no_QA_records_imported": true
}
@@ -0,0 +1,10 @@
{
"at": "2026-10-15T15:11:24+00:00",
"expected_QA_fingerprint": "d776e2c9eded8ab3c6437d8bdb16c099bb3e9c183a8565b044fcc71d352c600c",
"target": {
"database": "stability_consumers_20261011_084534_test",
"port": 55441
},
"method": "Existing installer fingerprint; no functional test or active write",
"active_changes": 0
}
@@ -0,0 +1,265 @@
{
"at": "2026-10-15T15:23:54.295853+00:00",
"candidate": "B-final-fabf722bc8c6",
"C137": true,
"sources": {
"app/Http/Middleware/HandleInertiaRequests.php": "e117d366ce411944fd560b5b8117853859532e255bff5e732f1874a1eac70979",
"app/Services/OpportunityCanonicalContract.php": "cf16600559fd3b6afb660845ee5e2360a63c4915ae9de5297803c53afda4f617",
"app/Services/OpportunityProfileWorkflow.php": "1d05a8e445c421364a534323e447b8cff84be2254d5f335ef1a1a4a2b18fe365",
"app/Services/InvestorPath.php": "7734420bfe2fcee0e49a3ca759987d54877844afb68bbba0f2a6ec3d1ec33269",
"app/Http/Controllers/LandAssistanceController.php": "3177919b63517064d36f977b7f779bd4d7061329c98c8b3710978c179a420031",
"resources/js/pages/land-assistance/form.tsx": "f9357ac8797ac2a0ba8d9a2022fb5c466d8afc55c57ed02deb144f1bf582f6cf",
"app/Http/Controllers/ExistingBusinessController.php": "ab085d31582b93c913fd5f0657c557b8f1d893cfb557a52302894a0f05956e7d",
"app/Services/CountryCatalogue.php": "fc0561dd0ee0e4c8340450892fcfb1c8678a7dd420428c60eb3890b2d82d9312",
"resources/js/pages/investment/business-interest.tsx": "2785ebeba2a4756f029514cb4ca2a6d8b312d2c292b5b71e2761b431c3e3dc7c",
"app/Services/OpportunityContacts.php": "d186abf83a959069c61b837a2424ce78719286e32d94672e3eedbe46f419121a",
"app/Services/OpportunityResources.php": "21adfc77be4810576b64e07d4d1c1adef69ea6d34f0b67d959631593fe8282b2",
"app/Services/ExistingBusinessIntake.php": "3ef03e137ff8241b2bd3ea64e00a0006de68ac20703edbbbb06d2837d09cbd1e",
"app/Services/InvestmentCatalogue.php": "948c9b78f892665700ed324d6e1ac92b591735f120236d86b13b58a1db39d0d5",
"app/Http/Controllers/PortalManagementController.php": "f03dd52e6072d2f745a1ed8ab6725a93182281c1e5cb507ed31c7e017cecb878",
"app/Services/OpportunityCategoryFields.php": "f452092648f673a672277b2234294348e3ad9a1a601aa493bcac01851a5d9558",
"resources/js/pages/investor-path/show.tsx": "db861e5e3a850ee571fda0299cefc4451edbf7ac373ee0d811c73d2d62539284",
"app/Policies/ExistingBusinessPolicy.php": "f06f3f3a9676e8659ee9e21c4fd04610f4f44664f692ccd7307b6c697bee9d4d",
"resources/js/pages/investment/shared.tsx": "d40eac734af27c4bb79f3a968da18a909d26c5890795508dda4f1180b0aa5ecb",
"resources/js/pages/investment/catalogue.tsx": "99707526863691eeef0d3c7971b6a3399d193f8e9fc2ade25ce1dbf2fd866b11",
"app/Models/Opportunity.php": "db3ed93d14040c55888eee7f13d1e3eadd4cae5786ff525b03cf77a56f712dd2",
"resources/js/pages/investment/detail.tsx": "048c70bb3fa9671721d2a0c0361935df5336c39e46b2d71bb16de29e25d5dd88",
"resources/js/components/opportunity-canonical-fields.tsx": "ca5f07627707f0a7a75ea1c7e3fed9bb8381917a07e85d6401242c9f2d87d9eb",
"app/Services/InvestmentRelations.php": "436e2e0e886741ee7e6440a447566f5c1ab0e9cad7e8fc88d298a5682bc2b92f",
"app/Http/Requests/StoreLandAssistanceCaseRequest.php": "2b3f24698e98f7262dfdd1df963ae8cf0f347f3b338c072e3d8f524c05c49ce4",
"resources/js/components/portal-grouped-menu.tsx": "a9ff5bc1ef0126f67a0f00cc13dd3fe087af98a0bfad5feb3cb8fe13214901a3",
"resources/js/pages/land-assistance/case.tsx": "ea1937b9ee8ea641ecbcff588ebea06c8aac59762c9f800b11bdf908f69b54d9",
"routes/land-assistance.php": "76522b6b78ab1a0319605aea5b57cca188e60a09ec2b5a6af4930ffb464b2410",
"app/Services/OpportunityReviewMateriality.php": "afcf465a51a7dab1ff9f50d41243407b5e9d83aeb85fb5ef0af3ebacdf9b7eaf",
"resources/js/lib/portal-navigation.ts": "fc2a4986eb48795024e8501983ce35f8fa772198be911183b329ccafb888ec62",
"resources/js/components/opportunity-profile-actions.tsx": "ae26baa8aa60b4c6c20093a332c4d26644a67ee0ab3e511c995ea7327133bb44",
"resources/js/pages/management/opportunity-draft.tsx": "4b6acdc5565f8c357fb3df6ed3cbae905b52cf908008479aa4f00593ce5dc8c3",
"resources/js/lib/profile-json.ts": "fdf04c41e4e6e4e2b9efd3ffb0e5cbc9c91fc281fd99caf63a6e64652ca5b69c",
"app/Http/Controllers/OpportunityManagementController.php": "a7ab08036d869d568c1a38d82c37cf94574881a322882c772e0ac6d16ac4c4d0",
"resources/js/pages/investment/business-wizard.tsx": "e97086260bee631f3a5a0f78535ed8e9664597bfb1d9a44af8e9ff6872271c5c",
"resources/js/pages/investment/business.tsx": "8d209da93ae09347113e21dde44e60fbe620525401170f60b19064556cbe2ca2",
"resources/js/pages/partnerships/room.tsx": "fea8a156ee7ff8b24492ec0bfe5e61ab4d6ecefe588f65bec67909fc704df53a"
},
"added_assets": [
"assets/PortalInvestidor-B1b3WKdU.js",
"assets/PortalInvestidor-BgL6dTJ9.js",
"assets/administration-2WaaHIKU.js",
"assets/administration-4iX3lyfJ.js",
"assets/ai-C1AwaRj6.js",
"assets/ai-DQrxdnH6.js",
"assets/analysis-Buws7paD.js",
"assets/analysis-CD4pUStB.js",
"assets/app-6koffaPt.js",
"assets/app-_QxUM8Uv.js",
"assets/appearance-Cc2zP-Sd.js",
"assets/appearance-dMBBCbrF.js",
"assets/audit-BVplYILe.js",
"assets/audit-IKTPV-c0.js",
"assets/bootstrap-confirmation-Bjm845T7.js",
"assets/bootstrap-confirmation-zU1pT5Kx.js",
"assets/business-D6sGcu4f.js",
"assets/business-Dx-g9F1l.js",
"assets/business-interest-DMzRJKcE.js",
"assets/business-interest-DwzIH9cJ.js",
"assets/business-marketplace-16_YFmUF.js",
"assets/business-marketplace-Bha1dEfr.js",
"assets/business-objects-BRSsWpdD.js",
"assets/business-objects-DuARIRpa.js",
"assets/business-opportunity-BNbAOFL9.js",
"assets/business-opportunity-DNToO3uL.js",
"assets/business-verifications-2Al7Pg8m.js",
"assets/business-verifications-Xydae-ss.js",
"assets/business-wizard-B2JTxZMO.js",
"assets/business-wizard-CweTzeAm.js",
"assets/businesses-HEmaf_kQ.js",
"assets/businesses-QPzv94h1.js",
"assets/case-B3iezsz3.js",
"assets/case-B7a3k3tp.js",
"assets/case-jhW1p_fJ.js",
"assets/catalog-BwNtwLxB.js",
"assets/catalog-DfcqZxWM.js",
"assets/catalogue-BmxB6oqs.js",
"assets/catalogue-BxoE4EAL.js",
"assets/catalogue-CyaEXEUk.js",
"assets/catalogue-DNWlydH2.js",
"assets/catalogue-DzIlCfaf.js",
"assets/catalogue-Zy33X5RY.js",
"assets/confirm-password-DOsJGE-_.js",
"assets/confirm-password-DoW48TlT.js",
"assets/context-BCjd3hOB.js",
"assets/context-ChrStmRt.js",
"assets/conversation-CVySJ5Os.js",
"assets/conversation-Lbuxtg60.js",
"assets/convert-CFqWFsBC.js",
"assets/convert-Cmif6Y0u.js",
"assets/dashboard-B7H-NvB6.js",
"assets/dashboard-Bv6vwdLI.js",
"assets/dashboard-BvCddPdb.js",
"assets/dashboard-C2C8-DQM.js",
"assets/desk-internal-operations-BgotJDzO.js",
"assets/desk-internal-operations-ynG9LTO4.js",
"assets/detail-BIfHtFTv.js",
"assets/detail-MMkJ03oN.js",
"assets/detail-lc1sZGLv.js",
"assets/detail-xVTgKqyJ.js",
"assets/dialog-BYzV5tSn.js",
"assets/dialog-DUS-YcSD.js",
"assets/document-BHIjQVsT.js",
"assets/document-BwUuCxkg.js",
"assets/editor-2DyDAvVU.js",
"assets/editor-4WTAzpYk.js",
"assets/editor-CPltGApx.js",
"assets/editor-CzCsyqfx.js",
"assets/editor-Czh8O56e.js",
"assets/editor-Vvw00b7m.js",
"assets/education-CoSzu2ss.js",
"assets/education-DPfjwmlA.js",
"assets/fonts-DmGVJ3xF.css",
"assets/forgot-password-Brr18zQf.js",
"assets/forgot-password-NuXRKj0-.js",
"assets/form-BmewvnzL.js",
"assets/form-DRfnkICL.js",
"assets/history-BD0biKsC.js",
"assets/history-DEIq0T_f.js",
"assets/install-BOKZXUPn.js",
"assets/install-C1r0bHiP.js",
"assets/installation-CEmL5By5.js",
"assets/installation-CZ_bcFXw.js",
"assets/installation-CuUS64JQ.js",
"assets/installation-MMDaFe6E.js",
"assets/interactive-investment-map-BwEIJoHZ.js",
"assets/interactive-investment-map-kc25PBcM.js",
"assets/interest-De1GJygr.js",
"assets/interest-Dx3i-rDY.js",
"assets/interests-Bux6HtO3.js",
"assets/interests-DbjR9rUG.js",
"assets/investment-map-panel-D4UkHert.js",
"assets/investment-map-panel-DPH5OZg7.js",
"assets/investment-territory-Bj7E9cdW.js",
"assets/investment-territory-CZryDFzG.js",
"assets/investor-B2RRfbRM.js",
"assets/investor-CF8sXB4I.js",
"assets/investors-BCSy92l-.js",
"assets/investors-DO2PHXP6.js",
"assets/lead-BiFql0_x.js",
"assets/lead-Dw_nrk5k.js",
"assets/leads-6RFlgHCo.js",
"assets/leads-DKvcU0F-.js",
"assets/login-DHiqnqsd.js",
"assets/login-pFhq8f0A.js",
"assets/manage-BHwgBS--.js",
"assets/manage-CEXfP-bD.js",
"assets/notifications-B-eLBfv_.js",
"assets/notifications-D7YtOqH-.js",
"assets/noto-sans-400-normal-BTkUljjl.woff2",
"assets/noto-sans-400-normal-DPpKfCgK.woff",
"assets/noto-sans-500-normal-CDPngY5C.woff",
"assets/noto-sans-500-normal-DCA2Z9Cj.woff2",
"assets/noto-sans-600-normal-DVJMj_t0.woff",
"assets/noto-sans-600-normal-Dkgu5AE5.woff2",
"assets/noto-sans-700-normal-CrvTEWhy.woff2",
"assets/noto-sans-700-normal-ZyrKABVF.woff",
"assets/noto-serif-400-normal-BV_iYGc9.woff2",
"assets/noto-serif-400-normal-DT0cwSa_.woff",
"assets/noto-serif-600-normal-BiuDA9L7.woff2",
"assets/noto-serif-600-normal-RZopCp-J.woff",
"assets/noto-serif-700-normal-CIw17UNa.woff2",
"assets/noto-serif-700-normal-mX-AlFMT.woff",
"assets/opportunities-BeP1nUjV.js",
"assets/opportunities-BvUjkGMA.js",
"assets/opportunity-draft-CY3-taid.js",
"assets/opportunity-draft-DY2xk8f5.js",
"assets/opportunity-install-BEeEaRIi.js",
"assets/opportunity-install-LOjhly-M.js",
"assets/opportunity-origin-BieMJONP.js",
"assets/opportunity-origin-P65CBahN.js",
"assets/opportunity-resources-C4bqMI-S.js",
"assets/opportunity-resources-f8hcGJe0.js",
"assets/panel-DwBN6cRB.js",
"assets/panel-MPfKo4Gs.js",
"assets/passkey-verify-BHwbYqlV.js",
"assets/passkey-verify-CHbNONJw.js",
"assets/password-input-Bvqo4Od7.js",
"assets/password-input-CZEiv6-Y.js",
"assets/portfolio-BeA7vA21.js",
"assets/portfolio-vrkKu9n-.js",
"assets/profile-7FEFpszu.js",
"assets/profile-Df7SjInW.js",
"assets/profile-json-BC1mQPe5.js",
"assets/profile-kiqG9EDh.js",
"assets/profile-mFQ94cGy.js",
"assets/references-Q3ObwDEu.js",
"assets/references-a6GUerWr.js",
"assets/register-CRijmNdY.js",
"assets/register-Dz4XuOsS.js",
"assets/relationship-repair-BbPpEIow.js",
"assets/relationship-repair-NfFTKlpn.js",
"assets/request-BnuYhHmw.js",
"assets/request-CF7xQbtn.js",
"assets/request-DNLOT7Ur.js",
"assets/request-Dzpl-g3h.js",
"assets/reset-password-D3X50aA5.js",
"assets/reset-password-FH2pmEDN.js",
"assets/result-BaPIoTbf.js",
"assets/result-DoL7QLi4.js",
"assets/room-DtK7QZt7.js",
"assets/room-LM3pUYAr.js",
"assets/security-B_oLYs5-.js",
"assets/security-CP6MMYJw.js",
"assets/services-BZQcAJGT.js",
"assets/services-CoqWEvPN.js",
"assets/shared-BEDl7WFV.js",
"assets/shared-Bi0ozaSH.js",
"assets/shared-C9SLMUlq.js",
"assets/shared-CBz2_oAS.js",
"assets/shared-CJucoqgO.js",
"assets/shared-CNf7SPwM.js",
"assets/shared-CXW4I9EU.js",
"assets/shared-D5bkan45.js",
"assets/show-B3_nUTlb.js",
"assets/show-CRx_Kgt0.js",
"assets/show-DcySP7EF.js",
"assets/sources-BD4xHxsm.js",
"assets/sources-DqLhX3mx.js",
"assets/structure-geography-D0mJ03tA.js",
"assets/structure-geography-DjJYBqm1.js",
"assets/structures-BEUCF3vT.js",
"assets/structures-Bw3yjEkY.js",
"assets/submission-Bb710thW.js",
"assets/submission-BztVPQOB.js",
"assets/territory-associations-BghnoFKh.js",
"assets/territory-associations-DQCywWbt.js",
"assets/territory-geometry-import-BgUiqJjl.js",
"assets/territory-geometry-import-bSp4-HnZ.js",
"assets/territory-geometry-preview-Co-tMRm3.js",
"assets/territory-geometry-preview-DqO4V0-r.js",
"assets/two-factor-challenge-C-j2ixF_.js",
"assets/two-factor-challenge-DzymIfIc.js",
"assets/value-network-BGoAnXyl.js",
"assets/value-network-Bw5_SMDf.js",
"assets/verify-email-DC21S6LB.js",
"assets/verify-email-DGF0VDk6.js",
"assets/welcome-CPCJPF06.js",
"assets/welcome-SvYVRhja.js",
"assets/workspace-B8XhXQw8.js",
"assets/workspace-Bo7B3eQ-.js",
"assets/workspace-CtTfcNTT.js",
"assets/workspace-Dm3sNpo2.js",
"assets/zone-BTGy6_nX.js",
"assets/zone-H5olHugq.js",
"assets/zone-attachments-C0x5nayn.js",
"assets/zone-attachments-CANe4XzA.js",
"assets/zone-map-BQAAUcFA.js",
"assets/zone-map-DKg4YJ5O.js",
"assets/zone-relations-BhHp793j.js",
"assets/zone-relations-D-lZGYpC.js",
"assets/zones-BHSVii1k.js",
"assets/zones-PkKrJeXJ.js"
],
"path_flag_enabled": false,
"maintenance_started": true,
"maintenance_ended": true,
"190000_installed": false,
"no_QA_data_imported": true,
"result": "sources_and_build_delivered; path still disabled; authenticated190000 pending"
}
@@ -0,0 +1,12 @@
{
"at": "2026-10-15T15:28:01.062419+00:00",
"setting": "INVESTOR_PATH_ENABLED",
"before": false,
"after": true,
"only_one_setting_added": true,
"before_was_default_false": true,
"env_before_sha256": "43cfd63151e6aa4e759ad90d13d3f3208b4ece296608c3324b509a619bf43e90",
"env_after_sha256": "754c288cbfdaac0d34ba91620c0d45cf6f965db348573b0ba59899ca71dbf241",
"installed_evidence_sha256": "2d1a6ce5a81419119bb152aceb964af8e53d1c3aee874f2dfc8043463fa24b28",
"credentials_COUNTRY02_and_other_settings_preserved": true
}
@@ -0,0 +1,27 @@
{
"at": "2026-10-15T15:09:24+00:00",
"candidate": "B-final-fabf722bc8c6",
"C137_included": true,
"target": {
"database": "investemoz",
"port": 5432
},
"restore_target": {
"database": "b_active_before_20261015_150846_test",
"port": 55441
},
"restore_verified": true,
"files_verified": true,
"tables": 295,
"sequences": 31,
"restored_table_hashes_equal": true,
"private_directory": "C:\/Users\/macbook\/.config\/investmoz\/B-active-before-20261015_150846",
"dump_sha256": "f234e33ce8498ac7def1764649b6ead9a1f94bbac6b1d9cda26f79535eff5278",
"files_sha256": "6e903c8d743c5a2dfe0dbee1cc113b52803411aecc037c09004b87e57d8f5d53",
"file_count": 815,
"document_files": 4,
"preexisting_unavailable_document_count": 0,
"190000_before": 0,
"path_flag_before": false,
"active_business_writes": 0
}
@@ -0,0 +1,53 @@
{
"at": "2026-10-15T15:28:02+00:00",
"target": {
"database": "investemoz",
"port": 5432
},
"SQL_read_only": true,
"installed": true,
"migration_ledger": [
{
"migration": "2026_10_09_190000_prepare_investor_path",
"batch": 47
}
],
"columns": [
{
"table_name": "investor_journeys",
"column_name": "path_definition_id",
"data_type": "uuid",
"is_nullable": "YES"
},
{
"table_name": "journey_steps",
"column_name": "path_detail",
"data_type": "text",
"is_nullable": "YES"
}
],
"definition": {
"id": "61000919-0000-4000-8000-000000000001",
"code": "investor-path-19",
"version_no": 1,
"status": "published"
},
"audit": {
"actor_user_id": 2,
"at": "2026-10-15 15:27:09.066394+00",
"code_hash": "d776e2c9eded8ab3c6437d8bdb16c099bb3e9c183a8565b044fcc71d352c600c"
},
"path_enabled": true,
"existing_journeys_bound": 0,
"existing_step_details": 0,
"counts": {
"desk_cases": 1,
"desk_requests": 0,
"desk_documents": 0,
"desk_messages": 0,
"tasks": 0,
"investor_accounts": 2,
"investment_submissions": 3
},
"pending_migrations": []
}
@@ -0,0 +1,53 @@
{
"at": "2026-10-15T15:27:38+00:00",
"target": {
"database": "investemoz",
"port": 5432
},
"SQL_read_only": true,
"installed": true,
"migration_ledger": [
{
"migration": "2026_10_09_190000_prepare_investor_path",
"batch": 47
}
],
"columns": [
{
"table_name": "investor_journeys",
"column_name": "path_definition_id",
"data_type": "uuid",
"is_nullable": "YES"
},
{
"table_name": "journey_steps",
"column_name": "path_detail",
"data_type": "text",
"is_nullable": "YES"
}
],
"definition": {
"id": "61000919-0000-4000-8000-000000000001",
"code": "investor-path-19",
"version_no": 1,
"status": "published"
},
"audit": {
"actor_user_id": 2,
"at": "2026-10-15 15:27:09.066394+00",
"code_hash": "d776e2c9eded8ab3c6437d8bdb16c099bb3e9c183a8565b044fcc71d352c600c"
},
"path_enabled": false,
"existing_journeys_bound": 0,
"existing_step_details": 0,
"counts": {
"desk_cases": 1,
"desk_requests": 0,
"desk_documents": 0,
"desk_messages": 0,
"tasks": 0,
"investor_accounts": 2,
"investment_submissions": 3
},
"pending_migrations": []
}
@@ -0,0 +1,71 @@
{
"at": "2026-10-15T15:26:55.290298+00:00",
"result": "existing accepted evidence reconciled; no tests repeated",
"code_hash": "d776e2c9eded8ab3c6437d8bdb16c099bb3e9c183a8565b044fcc71d352c600c",
"evidence": [
{
"path": "outputs/investmoz-audit-current-20261012/B-activation-Tempo-authorization-20261015.json",
"sha256": "99a631ff3b0608bfaee135b67d59c6587d78588fb6be1bd962f63aef8381f8a7"
},
{
"path": "outputs/investmoz-audit-current-20261012/B-activation-fresh-backup-20261015.json",
"sha256": "21d0f431056943a476b0233d6669dc325c86a678beb59c5aa66a89991f3dd928"
},
{
"path": "outputs/investmoz-audit-current-20261012/B-activation-file-switch-20261015.json",
"sha256": "49dd33e24240ef935920016412ec51d849e2e1fe8fe5b435bdccec60709f889c"
},
{
"path": "outputs/investmoz-audit-current-20261012/acceptance-396c-results.json",
"sha256": "374a4829c22a6db2355b4d3a400a731a65088a8da071fbfe5534e750b3385578"
},
{
"path": "outputs/investmoz-audit-current-20261012/B-restored-clone-boot-20261015.json",
"sha256": "7744a5e941bef358e9b027fae036a8f2bd708d2e34c017add73d119291119ca9"
},
{
"path": "storage/app/private/investmoz-v2/portal-audit/investor-ab-chromium-20261010.json",
"sha256": "6b5a22e6fce8ed91be29a443e9c6ec5f30c26ac94e357fb7a5c5e3a2931ac2a1"
},
{
"path": "storage/app/private/investmoz-v2/portal-audit/investor-ab-remaining-chromium-20261010.json",
"sha256": "cbc3f7ea794e826c357e7479105839200f1db3215c64cf3e6236935e9c5aa69a"
},
{
"path": "storage/app/private/investmoz-v2/portal-audit/investor-ab-remaining-persistence-qa.json",
"sha256": "07a0c5ec7b1d950ab6728c2ca52156030d352c9e4d1bbad025b246c83e539e13"
},
{
"path": "storage/app/private/investmoz-v2/portal-audit/investor-path-http-qa.json",
"sha256": "e94e45019a0be2d122628b8d92ed94cac2e3e44d324ca3febc2cdbd194aa4ff0"
},
{
"path": "storage/app/private/investmoz-v2/portal-audit/investor-path-compatibility.json",
"sha256": "41fd82f281faa34f52346a965d905d6668acddfa599950af2f8f3bcc0519f016"
},
{
"path": "outputs/investmoz-audit-current-20261012/B-suplemento-C137-sequencia-final-20261015/COMPATIBILIDADE-ESTADO-INTERMEDIO.json",
"sha256": "942b29203d9c095b0bfc280db773d86ff3db18ae9d8054b51f57cd79390180a9"
}
],
"proofs": [
{
"file": "backup-proof.json",
"sha256": "2ed2016144330b3308eb2213f39e77fff87376d684af659f4e8357424443951a"
},
{
"file": "guidance-qa-evidence.json",
"sha256": "e1cac4c619b7025914fdec57f96cc2c209a9b8998254499653f38842aa70f505"
},
{
"file": "activation-compatibility.json",
"sha256": "c9791ad5aee9bd25c43f9699c4f129d33afa1abb8cb43b5a19ec5d13b415b21e"
},
{
"file": "investor-path-qa-evidence.json",
"sha256": "ee24f09f168827466f3ec5958f91dab93f36efb9b3630a0a82657095767a36e0"
}
],
"originals_preserved": true,
"installer_gates_changed": false
}
@@ -0,0 +1,7 @@
{
"private_staging": "C:\\Users\\macbook\\.config\\investmoz\\B-active-before-20261015_150846\\candidate-staging",
"source36_before_after_verified": true,
"candidate_ZIP_unchanged": true,
"backup_files_ZIP_CRC_verified": true,
"deployment_executed": false
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

@@ -0,0 +1,51 @@
{
"hash": "15fb629fd1bda557bec756f090b0b34a25db63cc342d8146074563671885891c",
"code_hash": "d776e2c9eded8ab3c6437d8bdb16c099bb3e9c183a8565b044fcc71d352c600c",
"installed": false,
"baseDeskInstalled": true,
"pathInstalled": false,
"pathEnabled": false,
"pathQaVerified": true,
"target": {
"database": "investemoz",
"port": 5432
},
"counts": {
"desk_cases": 1,
"desk_requests": 0,
"desk_documents": 0,
"desk_messages": 0,
"tasks": 0,
"investor_accounts": 2,
"investment_submissions": 3
},
"backupVerified": true,
"qaVerified": true,
"compatibilityVerified": true,
"backupDate": "2026-10-15T15:09:24+00:00",
"databaseReady": true,
"scanner": {
"available": true,
"engine": "ClamAV",
"engine_version": "1.5.4",
"signatures_at": {
"date": "2026-10-15 08:24:22.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"signature_age_hours": 7.042777777777777,
"reason_code": null
},
"pendingMigrations": [
"2026_10_09_190000_prepare_investor_path"
],
"rollback": "Revers\u00e3o vazia ensaiada em c\u00f3pia isolada. Com dados novos, preservar\/exportar pedidos e tarefas; o down recusa eliminar dados. Restauro integral s\u00f3 numa janela autorizada, ap\u00f3s reconciliar altera\u00e7\u00f5es posteriores ao backup.",
"changes": [
"Completar o Balc\u00e3o Virtual existente, preservando pedidos anteriores.",
"Acrescentar associa\u00e7\u00f5es opcionais ao investidor, projecto e percurso existentes.",
"Reutilizar tasks do CRM para ac\u00e7\u00f5es expressamente assumidas; sem envio externo.",
"Nenhuma publica\u00e7\u00e3o de servi\u00e7o, documento ou candidatura autom\u00e1tica.",
"Preparar duas colunas nas entidades existentes e uma vers\u00e3o publicada do percurso de 19 etapas. N\u00e3o converter dossiers existentes.",
"N\u00e3o habilitar a navega\u00e7\u00e3o por instala\u00e7\u00e3o: configura\u00e7\u00e3o INVESTOR_PATH_ENABLED permanece uma ac\u00e7\u00e3o separada."
]
}
@@ -0,0 +1,6 @@
<?php
ini_set('zend.exception_ignore_args','1');
$root=dirname(__DIR__,2); require $root.'/vendor/autoload.php'; $app=require $root.'/bootstrap/app.php';$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
$c=config('database.connections.'.config('database.default'));if($c['database']!=='investemoz'||(int)$c['port']!==5432)throw new RuntimeException('Destination mismatch');
Illuminate\Support\Facades\DB::beginTransaction();Illuminate\Support\Facades\DB::statement('SET TRANSACTION READ ONLY');
try{$s=app(App\Services\VirtualDeskInstallation::class);$hash=$s->fingerprint();if($hash!=='d776e2c9eded8ab3c6437d8bdb16c099bb3e9c183a8565b044fcc71d352c600c')throw new RuntimeException('Fingerprint mismatch: '.$hash);$p=$s->preview();file_put_contents(__DIR__.'/B-active-installer-preview-20261015.json',json_encode($p,JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));echo json_encode($p,JSON_THROW_ON_ERROR);}finally{Illuminate\Support\Facades\DB::rollBack();}
@@ -0,0 +1,65 @@
- navigation "Atalho para o conteúdo":
- link "Saltar para o conteúdo":
- /url: "#portal-content"
- banner:
- link "InvesteMoz":
- /url: /
- paragraph: Iniciativa privada e independente de apoio ao investimento. Orientação e acompanhamento internos; decisões oficiais cabem às instituições competentes.
- navigation "Sessão da conta":
- paragraph: "Sessão: Osmane Nala"
- button "Terminar sessão":
- text: Terminar sessão
- navigation "Áreas do portal":
- list:
- button "Explorar investimentos":
- text: Explorar investimentos
- generic: ▾
- button "Preparar o projecto":
- text: Preparar o projecto
- generic: ▾
- button "Serviços e apoio":
- text: Serviços e apoio
- generic: ▾
- button "Parcerias":
- text: Parcerias
- generic: ▾
- button "A minha área":
- text: A minha área
- generic: ▾
- button "Gestão":
- text: Gestão
- generic: ▾
- button "Perfil e oportunidades":
- text: Perfil e oportunidades
- generic: ▾
- navigation "Caminho de navegação":
- link "Início":
- /url: /
- generic: /
- generic: Os meus investimentos
- complementary "Assistente do percurso do investidor":
- button "Acompanhar o meu projecto neste portal"
- main:
- heading "Os meus investimentos" [level=1]
- paragraph: Prepare cada investimento no seu dossier. Pode trabalhar em várias etapas em paralelo.
- list
- paragraph: Ainda não criou um investimento neste percurso.
- heading "Preparar um investimento" [level=2]
- text: Título
- textbox "Título"
- checkbox "Autorizo reutilizar o meu perfil neste dossier privado."
- text: Autorizo reutilizar o meu perfil neste dossier privado.
- button "Criar e guardar dossier"
- navigation "Ferramentas":
- link "Simulador":
- /url: /simulador-fiscal
- link "Balcão":
- /url: /balcao-virtual/painel
- link "Oportunidades guardadas":
- /url: /investidor
- link "Painel":
- /url: /dashboard
- complementary "Contacto de apoio ao investidor":
- link "Contactar Apoio ao Investidor":
- /url: /apoio
- region "Notifications alt+T"
@@ -0,0 +1,16 @@
{
"date": "2026-10-15",
"authority": "Tempo, Lda — instrução expressa do responsável na conversa",
"user_statement": "A Tempo autoriza",
"context": "Autoriza a proposta imediatamente anterior e os quatro pontos nela reunidos.",
"candidate": "B-final-fabf722bc8c6",
"candidate_SHA256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"supplement_SHA256": "182fb269536aa7bd84b8694ec54d1b39bf5b072abe91d0f4b1284389755fc620",
"C137_inclusion_and_documented_limitations_accepted": true,
"install_only_190000_if_absent_via_existing_authenticated_action": true,
"enable_INVESTOR_PATH_ENABLED_only_after_verification": true,
"fresh_destination_backup_restore_and_reversal_required": true,
"preserve_COUNTRY02_services_and_data": true,
"repeat_12_accepted_criteria": false,
"other_changes_authorized": false
}
@@ -0,0 +1,47 @@
{
"at": "2026-10-15T15:28:53+00:00",
"method": "Read-only repeatable snapshot vs verified preactivation restore; new nullable columns projected out for preexisting journeys.",
"SQL_read_only": true,
"tables_checked": 295,
"tables_exactly_equal": 289,
"differences": {
"\"public\".\"audit_events\"": {
"before": 175,
"after": 176,
"prior_rows_changed_or_removed": 0,
"new_or_changed_rows": 1
},
"\"public\".\"cache\"": {
"before": 94,
"after": 95,
"prior_rows_changed_or_removed": 4,
"new_or_changed_rows": 5
},
"\"public\".\"investor_journeys\"": {
"before": 1,
"after": 1,
"prior_rows_changed_or_removed": 0,
"new_or_changed_rows": 0
},
"\"public\".\"migrations\"": {
"before": 82,
"after": 83,
"prior_rows_changed_or_removed": 0,
"new_or_changed_rows": 1
},
"\"public\".\"questionnaire_versions\"": {
"before": 1,
"after": 2,
"prior_rows_changed_or_removed": 0,
"new_or_changed_rows": 1
},
"\"public\".\"sessions\"": {
"before": 6,
"after": 6,
"prior_rows_changed_or_removed": 1,
"new_or_changed_rows": 1
}
},
"all_prior_business_rows_preserved": true,
"no_QA_records_imported": true
}
@@ -0,0 +1,265 @@
{
"at": "2026-10-15T15:23:54.295853+00:00",
"candidate": "B-final-fabf722bc8c6",
"C137": true,
"sources": {
"app/Http/Middleware/HandleInertiaRequests.php": "e117d366ce411944fd560b5b8117853859532e255bff5e732f1874a1eac70979",
"app/Services/OpportunityCanonicalContract.php": "cf16600559fd3b6afb660845ee5e2360a63c4915ae9de5297803c53afda4f617",
"app/Services/OpportunityProfileWorkflow.php": "1d05a8e445c421364a534323e447b8cff84be2254d5f335ef1a1a4a2b18fe365",
"app/Services/InvestorPath.php": "7734420bfe2fcee0e49a3ca759987d54877844afb68bbba0f2a6ec3d1ec33269",
"app/Http/Controllers/LandAssistanceController.php": "3177919b63517064d36f977b7f779bd4d7061329c98c8b3710978c179a420031",
"resources/js/pages/land-assistance/form.tsx": "f9357ac8797ac2a0ba8d9a2022fb5c466d8afc55c57ed02deb144f1bf582f6cf",
"app/Http/Controllers/ExistingBusinessController.php": "ab085d31582b93c913fd5f0657c557b8f1d893cfb557a52302894a0f05956e7d",
"app/Services/CountryCatalogue.php": "fc0561dd0ee0e4c8340450892fcfb1c8678a7dd420428c60eb3890b2d82d9312",
"resources/js/pages/investment/business-interest.tsx": "2785ebeba2a4756f029514cb4ca2a6d8b312d2c292b5b71e2761b431c3e3dc7c",
"app/Services/OpportunityContacts.php": "d186abf83a959069c61b837a2424ce78719286e32d94672e3eedbe46f419121a",
"app/Services/OpportunityResources.php": "21adfc77be4810576b64e07d4d1c1adef69ea6d34f0b67d959631593fe8282b2",
"app/Services/ExistingBusinessIntake.php": "3ef03e137ff8241b2bd3ea64e00a0006de68ac20703edbbbb06d2837d09cbd1e",
"app/Services/InvestmentCatalogue.php": "948c9b78f892665700ed324d6e1ac92b591735f120236d86b13b58a1db39d0d5",
"app/Http/Controllers/PortalManagementController.php": "f03dd52e6072d2f745a1ed8ab6725a93182281c1e5cb507ed31c7e017cecb878",
"app/Services/OpportunityCategoryFields.php": "f452092648f673a672277b2234294348e3ad9a1a601aa493bcac01851a5d9558",
"resources/js/pages/investor-path/show.tsx": "db861e5e3a850ee571fda0299cefc4451edbf7ac373ee0d811c73d2d62539284",
"app/Policies/ExistingBusinessPolicy.php": "f06f3f3a9676e8659ee9e21c4fd04610f4f44664f692ccd7307b6c697bee9d4d",
"resources/js/pages/investment/shared.tsx": "d40eac734af27c4bb79f3a968da18a909d26c5890795508dda4f1180b0aa5ecb",
"resources/js/pages/investment/catalogue.tsx": "99707526863691eeef0d3c7971b6a3399d193f8e9fc2ade25ce1dbf2fd866b11",
"app/Models/Opportunity.php": "db3ed93d14040c55888eee7f13d1e3eadd4cae5786ff525b03cf77a56f712dd2",
"resources/js/pages/investment/detail.tsx": "048c70bb3fa9671721d2a0c0361935df5336c39e46b2d71bb16de29e25d5dd88",
"resources/js/components/opportunity-canonical-fields.tsx": "ca5f07627707f0a7a75ea1c7e3fed9bb8381917a07e85d6401242c9f2d87d9eb",
"app/Services/InvestmentRelations.php": "436e2e0e886741ee7e6440a447566f5c1ab0e9cad7e8fc88d298a5682bc2b92f",
"app/Http/Requests/StoreLandAssistanceCaseRequest.php": "2b3f24698e98f7262dfdd1df963ae8cf0f347f3b338c072e3d8f524c05c49ce4",
"resources/js/components/portal-grouped-menu.tsx": "a9ff5bc1ef0126f67a0f00cc13dd3fe087af98a0bfad5feb3cb8fe13214901a3",
"resources/js/pages/land-assistance/case.tsx": "ea1937b9ee8ea641ecbcff588ebea06c8aac59762c9f800b11bdf908f69b54d9",
"routes/land-assistance.php": "76522b6b78ab1a0319605aea5b57cca188e60a09ec2b5a6af4930ffb464b2410",
"app/Services/OpportunityReviewMateriality.php": "afcf465a51a7dab1ff9f50d41243407b5e9d83aeb85fb5ef0af3ebacdf9b7eaf",
"resources/js/lib/portal-navigation.ts": "fc2a4986eb48795024e8501983ce35f8fa772198be911183b329ccafb888ec62",
"resources/js/components/opportunity-profile-actions.tsx": "ae26baa8aa60b4c6c20093a332c4d26644a67ee0ab3e511c995ea7327133bb44",
"resources/js/pages/management/opportunity-draft.tsx": "4b6acdc5565f8c357fb3df6ed3cbae905b52cf908008479aa4f00593ce5dc8c3",
"resources/js/lib/profile-json.ts": "fdf04c41e4e6e4e2b9efd3ffb0e5cbc9c91fc281fd99caf63a6e64652ca5b69c",
"app/Http/Controllers/OpportunityManagementController.php": "a7ab08036d869d568c1a38d82c37cf94574881a322882c772e0ac6d16ac4c4d0",
"resources/js/pages/investment/business-wizard.tsx": "e97086260bee631f3a5a0f78535ed8e9664597bfb1d9a44af8e9ff6872271c5c",
"resources/js/pages/investment/business.tsx": "8d209da93ae09347113e21dde44e60fbe620525401170f60b19064556cbe2ca2",
"resources/js/pages/partnerships/room.tsx": "fea8a156ee7ff8b24492ec0bfe5e61ab4d6ecefe588f65bec67909fc704df53a"
},
"added_assets": [
"assets/PortalInvestidor-B1b3WKdU.js",
"assets/PortalInvestidor-BgL6dTJ9.js",
"assets/administration-2WaaHIKU.js",
"assets/administration-4iX3lyfJ.js",
"assets/ai-C1AwaRj6.js",
"assets/ai-DQrxdnH6.js",
"assets/analysis-Buws7paD.js",
"assets/analysis-CD4pUStB.js",
"assets/app-6koffaPt.js",
"assets/app-_QxUM8Uv.js",
"assets/appearance-Cc2zP-Sd.js",
"assets/appearance-dMBBCbrF.js",
"assets/audit-BVplYILe.js",
"assets/audit-IKTPV-c0.js",
"assets/bootstrap-confirmation-Bjm845T7.js",
"assets/bootstrap-confirmation-zU1pT5Kx.js",
"assets/business-D6sGcu4f.js",
"assets/business-Dx-g9F1l.js",
"assets/business-interest-DMzRJKcE.js",
"assets/business-interest-DwzIH9cJ.js",
"assets/business-marketplace-16_YFmUF.js",
"assets/business-marketplace-Bha1dEfr.js",
"assets/business-objects-BRSsWpdD.js",
"assets/business-objects-DuARIRpa.js",
"assets/business-opportunity-BNbAOFL9.js",
"assets/business-opportunity-DNToO3uL.js",
"assets/business-verifications-2Al7Pg8m.js",
"assets/business-verifications-Xydae-ss.js",
"assets/business-wizard-B2JTxZMO.js",
"assets/business-wizard-CweTzeAm.js",
"assets/businesses-HEmaf_kQ.js",
"assets/businesses-QPzv94h1.js",
"assets/case-B3iezsz3.js",
"assets/case-B7a3k3tp.js",
"assets/case-jhW1p_fJ.js",
"assets/catalog-BwNtwLxB.js",
"assets/catalog-DfcqZxWM.js",
"assets/catalogue-BmxB6oqs.js",
"assets/catalogue-BxoE4EAL.js",
"assets/catalogue-CyaEXEUk.js",
"assets/catalogue-DNWlydH2.js",
"assets/catalogue-DzIlCfaf.js",
"assets/catalogue-Zy33X5RY.js",
"assets/confirm-password-DOsJGE-_.js",
"assets/confirm-password-DoW48TlT.js",
"assets/context-BCjd3hOB.js",
"assets/context-ChrStmRt.js",
"assets/conversation-CVySJ5Os.js",
"assets/conversation-Lbuxtg60.js",
"assets/convert-CFqWFsBC.js",
"assets/convert-Cmif6Y0u.js",
"assets/dashboard-B7H-NvB6.js",
"assets/dashboard-Bv6vwdLI.js",
"assets/dashboard-BvCddPdb.js",
"assets/dashboard-C2C8-DQM.js",
"assets/desk-internal-operations-BgotJDzO.js",
"assets/desk-internal-operations-ynG9LTO4.js",
"assets/detail-BIfHtFTv.js",
"assets/detail-MMkJ03oN.js",
"assets/detail-lc1sZGLv.js",
"assets/detail-xVTgKqyJ.js",
"assets/dialog-BYzV5tSn.js",
"assets/dialog-DUS-YcSD.js",
"assets/document-BHIjQVsT.js",
"assets/document-BwUuCxkg.js",
"assets/editor-2DyDAvVU.js",
"assets/editor-4WTAzpYk.js",
"assets/editor-CPltGApx.js",
"assets/editor-CzCsyqfx.js",
"assets/editor-Czh8O56e.js",
"assets/editor-Vvw00b7m.js",
"assets/education-CoSzu2ss.js",
"assets/education-DPfjwmlA.js",
"assets/fonts-DmGVJ3xF.css",
"assets/forgot-password-Brr18zQf.js",
"assets/forgot-password-NuXRKj0-.js",
"assets/form-BmewvnzL.js",
"assets/form-DRfnkICL.js",
"assets/history-BD0biKsC.js",
"assets/history-DEIq0T_f.js",
"assets/install-BOKZXUPn.js",
"assets/install-C1r0bHiP.js",
"assets/installation-CEmL5By5.js",
"assets/installation-CZ_bcFXw.js",
"assets/installation-CuUS64JQ.js",
"assets/installation-MMDaFe6E.js",
"assets/interactive-investment-map-BwEIJoHZ.js",
"assets/interactive-investment-map-kc25PBcM.js",
"assets/interest-De1GJygr.js",
"assets/interest-Dx3i-rDY.js",
"assets/interests-Bux6HtO3.js",
"assets/interests-DbjR9rUG.js",
"assets/investment-map-panel-D4UkHert.js",
"assets/investment-map-panel-DPH5OZg7.js",
"assets/investment-territory-Bj7E9cdW.js",
"assets/investment-territory-CZryDFzG.js",
"assets/investor-B2RRfbRM.js",
"assets/investor-CF8sXB4I.js",
"assets/investors-BCSy92l-.js",
"assets/investors-DO2PHXP6.js",
"assets/lead-BiFql0_x.js",
"assets/lead-Dw_nrk5k.js",
"assets/leads-6RFlgHCo.js",
"assets/leads-DKvcU0F-.js",
"assets/login-DHiqnqsd.js",
"assets/login-pFhq8f0A.js",
"assets/manage-BHwgBS--.js",
"assets/manage-CEXfP-bD.js",
"assets/notifications-B-eLBfv_.js",
"assets/notifications-D7YtOqH-.js",
"assets/noto-sans-400-normal-BTkUljjl.woff2",
"assets/noto-sans-400-normal-DPpKfCgK.woff",
"assets/noto-sans-500-normal-CDPngY5C.woff",
"assets/noto-sans-500-normal-DCA2Z9Cj.woff2",
"assets/noto-sans-600-normal-DVJMj_t0.woff",
"assets/noto-sans-600-normal-Dkgu5AE5.woff2",
"assets/noto-sans-700-normal-CrvTEWhy.woff2",
"assets/noto-sans-700-normal-ZyrKABVF.woff",
"assets/noto-serif-400-normal-BV_iYGc9.woff2",
"assets/noto-serif-400-normal-DT0cwSa_.woff",
"assets/noto-serif-600-normal-BiuDA9L7.woff2",
"assets/noto-serif-600-normal-RZopCp-J.woff",
"assets/noto-serif-700-normal-CIw17UNa.woff2",
"assets/noto-serif-700-normal-mX-AlFMT.woff",
"assets/opportunities-BeP1nUjV.js",
"assets/opportunities-BvUjkGMA.js",
"assets/opportunity-draft-CY3-taid.js",
"assets/opportunity-draft-DY2xk8f5.js",
"assets/opportunity-install-BEeEaRIi.js",
"assets/opportunity-install-LOjhly-M.js",
"assets/opportunity-origin-BieMJONP.js",
"assets/opportunity-origin-P65CBahN.js",
"assets/opportunity-resources-C4bqMI-S.js",
"assets/opportunity-resources-f8hcGJe0.js",
"assets/panel-DwBN6cRB.js",
"assets/panel-MPfKo4Gs.js",
"assets/passkey-verify-BHwbYqlV.js",
"assets/passkey-verify-CHbNONJw.js",
"assets/password-input-Bvqo4Od7.js",
"assets/password-input-CZEiv6-Y.js",
"assets/portfolio-BeA7vA21.js",
"assets/portfolio-vrkKu9n-.js",
"assets/profile-7FEFpszu.js",
"assets/profile-Df7SjInW.js",
"assets/profile-json-BC1mQPe5.js",
"assets/profile-kiqG9EDh.js",
"assets/profile-mFQ94cGy.js",
"assets/references-Q3ObwDEu.js",
"assets/references-a6GUerWr.js",
"assets/register-CRijmNdY.js",
"assets/register-Dz4XuOsS.js",
"assets/relationship-repair-BbPpEIow.js",
"assets/relationship-repair-NfFTKlpn.js",
"assets/request-BnuYhHmw.js",
"assets/request-CF7xQbtn.js",
"assets/request-DNLOT7Ur.js",
"assets/request-Dzpl-g3h.js",
"assets/reset-password-D3X50aA5.js",
"assets/reset-password-FH2pmEDN.js",
"assets/result-BaPIoTbf.js",
"assets/result-DoL7QLi4.js",
"assets/room-DtK7QZt7.js",
"assets/room-LM3pUYAr.js",
"assets/security-B_oLYs5-.js",
"assets/security-CP6MMYJw.js",
"assets/services-BZQcAJGT.js",
"assets/services-CoqWEvPN.js",
"assets/shared-BEDl7WFV.js",
"assets/shared-Bi0ozaSH.js",
"assets/shared-C9SLMUlq.js",
"assets/shared-CBz2_oAS.js",
"assets/shared-CJucoqgO.js",
"assets/shared-CNf7SPwM.js",
"assets/shared-CXW4I9EU.js",
"assets/shared-D5bkan45.js",
"assets/show-B3_nUTlb.js",
"assets/show-CRx_Kgt0.js",
"assets/show-DcySP7EF.js",
"assets/sources-BD4xHxsm.js",
"assets/sources-DqLhX3mx.js",
"assets/structure-geography-D0mJ03tA.js",
"assets/structure-geography-DjJYBqm1.js",
"assets/structures-BEUCF3vT.js",
"assets/structures-Bw3yjEkY.js",
"assets/submission-Bb710thW.js",
"assets/submission-BztVPQOB.js",
"assets/territory-associations-BghnoFKh.js",
"assets/territory-associations-DQCywWbt.js",
"assets/territory-geometry-import-BgUiqJjl.js",
"assets/territory-geometry-import-bSp4-HnZ.js",
"assets/territory-geometry-preview-Co-tMRm3.js",
"assets/territory-geometry-preview-DqO4V0-r.js",
"assets/two-factor-challenge-C-j2ixF_.js",
"assets/two-factor-challenge-DzymIfIc.js",
"assets/value-network-BGoAnXyl.js",
"assets/value-network-Bw5_SMDf.js",
"assets/verify-email-DC21S6LB.js",
"assets/verify-email-DGF0VDk6.js",
"assets/welcome-CPCJPF06.js",
"assets/welcome-SvYVRhja.js",
"assets/workspace-B8XhXQw8.js",
"assets/workspace-Bo7B3eQ-.js",
"assets/workspace-CtTfcNTT.js",
"assets/workspace-Dm3sNpo2.js",
"assets/zone-BTGy6_nX.js",
"assets/zone-H5olHugq.js",
"assets/zone-attachments-C0x5nayn.js",
"assets/zone-attachments-CANe4XzA.js",
"assets/zone-map-BQAAUcFA.js",
"assets/zone-map-DKg4YJ5O.js",
"assets/zone-relations-BhHp793j.js",
"assets/zone-relations-D-lZGYpC.js",
"assets/zones-BHSVii1k.js",
"assets/zones-PkKrJeXJ.js"
],
"path_flag_enabled": false,
"maintenance_started": true,
"maintenance_ended": true,
"190000_installed": false,
"no_QA_data_imported": true,
"result": "sources_and_build_delivered; path still disabled; authenticated190000 pending"
}
@@ -0,0 +1,12 @@
{
"at": "2026-10-15T15:28:01.062419+00:00",
"setting": "INVESTOR_PATH_ENABLED",
"before": false,
"after": true,
"only_one_setting_added": true,
"before_was_default_false": true,
"env_before_sha256": "43cfd63151e6aa4e759ad90d13d3f3208b4ece296608c3324b509a619bf43e90",
"env_after_sha256": "754c288cbfdaac0d34ba91620c0d45cf6f965db348573b0ba59899ca71dbf241",
"installed_evidence_sha256": "2d1a6ce5a81419119bb152aceb964af8e53d1c3aee874f2dfc8043463fa24b28",
"credentials_COUNTRY02_and_other_settings_preserved": true
}
@@ -0,0 +1,27 @@
{
"at": "2026-10-15T15:09:24+00:00",
"candidate": "B-final-fabf722bc8c6",
"C137_included": true,
"target": {
"database": "investemoz",
"port": 5432
},
"restore_target": {
"database": "b_active_before_20261015_150846_test",
"port": 55441
},
"restore_verified": true,
"files_verified": true,
"tables": 295,
"sequences": 31,
"restored_table_hashes_equal": true,
"private_directory": "C:\/Users\/macbook\/.config\/investmoz\/B-active-before-20261015_150846",
"dump_sha256": "f234e33ce8498ac7def1764649b6ead9a1f94bbac6b1d9cda26f79535eff5278",
"files_sha256": "6e903c8d743c5a2dfe0dbee1cc113b52803411aecc037c09004b87e57d8f5d53",
"file_count": 815,
"document_files": 4,
"preexisting_unavailable_document_count": 0,
"190000_before": 0,
"path_flag_before": false,
"active_business_writes": 0
}
@@ -0,0 +1,53 @@
{
"at": "2026-10-15T15:28:02+00:00",
"target": {
"database": "investemoz",
"port": 5432
},
"SQL_read_only": true,
"installed": true,
"migration_ledger": [
{
"migration": "2026_10_09_190000_prepare_investor_path",
"batch": 47
}
],
"columns": [
{
"table_name": "investor_journeys",
"column_name": "path_definition_id",
"data_type": "uuid",
"is_nullable": "YES"
},
{
"table_name": "journey_steps",
"column_name": "path_detail",
"data_type": "text",
"is_nullable": "YES"
}
],
"definition": {
"id": "61000919-0000-4000-8000-000000000001",
"code": "investor-path-19",
"version_no": 1,
"status": "published"
},
"audit": {
"actor_user_id": 2,
"at": "2026-10-15 15:27:09.066394+00",
"code_hash": "d776e2c9eded8ab3c6437d8bdb16c099bb3e9c183a8565b044fcc71d352c600c"
},
"path_enabled": true,
"existing_journeys_bound": 0,
"existing_step_details": 0,
"counts": {
"desk_cases": 1,
"desk_requests": 0,
"desk_documents": 0,
"desk_messages": 0,
"tasks": 0,
"investor_accounts": 2,
"investment_submissions": 3
},
"pending_migrations": []
}
@@ -0,0 +1,53 @@
{
"at": "2026-10-15T15:27:38+00:00",
"target": {
"database": "investemoz",
"port": 5432
},
"SQL_read_only": true,
"installed": true,
"migration_ledger": [
{
"migration": "2026_10_09_190000_prepare_investor_path",
"batch": 47
}
],
"columns": [
{
"table_name": "investor_journeys",
"column_name": "path_definition_id",
"data_type": "uuid",
"is_nullable": "YES"
},
{
"table_name": "journey_steps",
"column_name": "path_detail",
"data_type": "text",
"is_nullable": "YES"
}
],
"definition": {
"id": "61000919-0000-4000-8000-000000000001",
"code": "investor-path-19",
"version_no": 1,
"status": "published"
},
"audit": {
"actor_user_id": 2,
"at": "2026-10-15 15:27:09.066394+00",
"code_hash": "d776e2c9eded8ab3c6437d8bdb16c099bb3e9c183a8565b044fcc71d352c600c"
},
"path_enabled": false,
"existing_journeys_bound": 0,
"existing_step_details": 0,
"counts": {
"desk_cases": 1,
"desk_requests": 0,
"desk_documents": 0,
"desk_messages": 0,
"tasks": 0,
"investor_accounts": 2,
"investment_submissions": 3
},
"pending_migrations": []
}
@@ -0,0 +1,71 @@
{
"at": "2026-10-15T15:26:55.290298+00:00",
"result": "existing accepted evidence reconciled; no tests repeated",
"code_hash": "d776e2c9eded8ab3c6437d8bdb16c099bb3e9c183a8565b044fcc71d352c600c",
"evidence": [
{
"path": "outputs/investmoz-audit-current-20261012/B-activation-Tempo-authorization-20261015.json",
"sha256": "99a631ff3b0608bfaee135b67d59c6587d78588fb6be1bd962f63aef8381f8a7"
},
{
"path": "outputs/investmoz-audit-current-20261012/B-activation-fresh-backup-20261015.json",
"sha256": "21d0f431056943a476b0233d6669dc325c86a678beb59c5aa66a89991f3dd928"
},
{
"path": "outputs/investmoz-audit-current-20261012/B-activation-file-switch-20261015.json",
"sha256": "49dd33e24240ef935920016412ec51d849e2e1fe8fe5b435bdccec60709f889c"
},
{
"path": "outputs/investmoz-audit-current-20261012/acceptance-396c-results.json",
"sha256": "374a4829c22a6db2355b4d3a400a731a65088a8da071fbfe5534e750b3385578"
},
{
"path": "outputs/investmoz-audit-current-20261012/B-restored-clone-boot-20261015.json",
"sha256": "7744a5e941bef358e9b027fae036a8f2bd708d2e34c017add73d119291119ca9"
},
{
"path": "storage/app/private/investmoz-v2/portal-audit/investor-ab-chromium-20261010.json",
"sha256": "6b5a22e6fce8ed91be29a443e9c6ec5f30c26ac94e357fb7a5c5e3a2931ac2a1"
},
{
"path": "storage/app/private/investmoz-v2/portal-audit/investor-ab-remaining-chromium-20261010.json",
"sha256": "cbc3f7ea794e826c357e7479105839200f1db3215c64cf3e6236935e9c5aa69a"
},
{
"path": "storage/app/private/investmoz-v2/portal-audit/investor-ab-remaining-persistence-qa.json",
"sha256": "07a0c5ec7b1d950ab6728c2ca52156030d352c9e4d1bbad025b246c83e539e13"
},
{
"path": "storage/app/private/investmoz-v2/portal-audit/investor-path-http-qa.json",
"sha256": "e94e45019a0be2d122628b8d92ed94cac2e3e44d324ca3febc2cdbd194aa4ff0"
},
{
"path": "storage/app/private/investmoz-v2/portal-audit/investor-path-compatibility.json",
"sha256": "41fd82f281faa34f52346a965d905d6668acddfa599950af2f8f3bcc0519f016"
},
{
"path": "outputs/investmoz-audit-current-20261012/B-suplemento-C137-sequencia-final-20261015/COMPATIBILIDADE-ESTADO-INTERMEDIO.json",
"sha256": "942b29203d9c095b0bfc280db773d86ff3db18ae9d8054b51f57cd79390180a9"
}
],
"proofs": [
{
"file": "backup-proof.json",
"sha256": "2ed2016144330b3308eb2213f39e77fff87376d684af659f4e8357424443951a"
},
{
"file": "guidance-qa-evidence.json",
"sha256": "e1cac4c619b7025914fdec57f96cc2c209a9b8998254499653f38842aa70f505"
},
{
"file": "activation-compatibility.json",
"sha256": "c9791ad5aee9bd25c43f9699c4f129d33afa1abb8cb43b5a19ec5d13b415b21e"
},
{
"file": "investor-path-qa-evidence.json",
"sha256": "ee24f09f168827466f3ec5958f91dab93f36efb9b3630a0a82657095767a36e0"
}
],
"originals_preserved": true,
"installer_gates_changed": false
}
@@ -0,0 +1,65 @@
- navigation "Atalho para o conteúdo":
- link "Saltar para o conteúdo":
- /url: "#portal-content"
- banner:
- link "InvesteMoz":
- /url: /
- paragraph: Iniciativa privada e independente de apoio ao investimento. Orientação e acompanhamento internos; decisões oficiais cabem às instituições competentes.
- navigation "Sessão da conta":
- paragraph: "Sessão: Osmane Nala"
- button "Terminar sessão":
- text: Terminar sessão
- navigation "Áreas do portal":
- list:
- button "Explorar investimentos":
- text: Explorar investimentos
- generic: ▾
- button "Preparar o projecto":
- text: Preparar o projecto
- generic: ▾
- button "Serviços e apoio":
- text: Serviços e apoio
- generic: ▾
- button "Parcerias":
- text: Parcerias
- generic: ▾
- button "A minha área":
- text: A minha área
- generic: ▾
- button "Gestão":
- text: Gestão
- generic: ▾
- button "Perfil e oportunidades":
- text: Perfil e oportunidades
- generic: ▾
- navigation "Caminho de navegação":
- link "Início":
- /url: /
- generic: /
- generic: Os meus investimentos
- complementary "Assistente do percurso do investidor":
- button "Acompanhar o meu projecto neste portal"
- main:
- heading "Os meus investimentos" [level=1]
- paragraph: Prepare cada investimento no seu dossier. Pode trabalhar em várias etapas em paralelo.
- list
- paragraph: Ainda não criou um investimento neste percurso.
- heading "Preparar um investimento" [level=2]
- text: Título
- textbox "Título"
- checkbox "Autorizo reutilizar o meu perfil neste dossier privado."
- text: Autorizo reutilizar o meu perfil neste dossier privado.
- button "Criar e guardar dossier"
- navigation "Ferramentas":
- link "Simulador":
- /url: /simulador-fiscal
- link "Balcão":
- /url: /balcao-virtual/painel
- link "Oportunidades guardadas":
- /url: /investidor
- link "Painel":
- /url: /dashboard
- complementary "Contacto de apoio ao investidor":
- link "Contactar Apoio ao Investidor":
- /url: /apoio
- region "Notifications alt+T"
@@ -0,0 +1,64 @@
{
"files": [
{
"path": "B-activation-data-preservation-20261015.json",
"sha256": "c465ed4176748adf8c8f8c77b4ccbc2d96e269f5a1ecf13749c85326ee0ff9cf",
"bytes": 1507
},
{
"path": "B-activation-file-switch-20261015.json",
"sha256": "49dd33e24240ef935920016412ec51d849e2e1fe8fe5b435bdccec60709f889c",
"bytes": 13184
},
{
"path": "B-activation-flag-20261015.json",
"sha256": "e466a9ed500f4932dff793b8f014d0d6648ba8d7a85117462e705eabc4a4fc08",
"bytes": 545
},
{
"path": "B-activation-fresh-backup-20261015.json",
"sha256": "21d0f431056943a476b0233d6669dc325c86a678beb59c5aa66a89991f3dd928",
"bytes": 901
},
{
"path": "B-activation-installed-20261015.json",
"sha256": "8186b08e6d3e3155906f94d46f5465f97f2342cedfee9ca585309ba9fb7b406b",
"bytes": 1392
},
{
"path": "B-activation-installed-before-flag-20261015.json",
"sha256": "2d1a6ce5a81419119bb152aceb964af8e53d1c3aee874f2dfc8043463fa24b28",
"bytes": 1393
},
{
"path": "B-activation-readiness-reconciliation-20261015.json",
"sha256": "eacd77a594f998f61e9897df246fe8a6b73789ec93436cb1d493cf2977e53eee",
"bytes": 3109
},
{
"path": "B-activation-Tempo-authorization-20261015.json",
"sha256": "99a631ff3b0608bfaee135b67d59c6587d78588fb6be1bd962f63aef8381f8a7",
"bytes": 870
},
{
"path": "B-active-installation-enabled-20261015.png",
"sha256": "06dfc49a6e68f5d85de41ca17e727a1f0a4b1b636228bd1fa33dca5306750f4e",
"bytes": 245956
},
{
"path": "B-active-path-open-20261015.txt",
"sha256": "926bb266eb395da940ee2b31f77a4abd8b4976daee5fa06d027db4e5868744f4",
"bytes": 2263
},
{
"path": "RESULTADO-ATIVACAO.json",
"sha256": "ac39a97b351b5526de3d41957d9bffadd8bf38d8113b0abd0d88c962696a8bff",
"bytes": 2065
},
{
"path": "RESULTADO-ATIVACAO.md",
"sha256": "df6314615e9ffd673c3a7318c530920f55830e30400f54ec6095536588dc32f9",
"bytes": 2248
}
]
}
@@ -0,0 +1,14 @@
{
"at": "2026-10-15T15:30:25.359710+00:00",
"result": "local integrity verified",
"zip": "investmoz-B-ativacao-concluida-20261015.zip",
"sha256": "bacefba6d72c3f36d8630ffc02e58f02fded3e71a44e71d4cddd6fc1a799cf83",
"bytes": 207963,
"manifest_sha256": "2b8f12684553d5395c83dc08aefdd403020fd73754198a22024b841553e9a8c9",
"result_sha256": "df6314615e9ffd673c3a7318c530920f55830e30400f54ec6095536588dc32f9",
"candidate_zip_sha256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"supplement_zip_sha256": "182fb269536aa7bd84b8694ec54d1b39bf5b072abe91d0f4b1284389755fc620",
"sources": 36,
"operational_activation_completed": true,
"accepted_functional_tests_repeated": 0
}
@@ -0,0 +1,39 @@
{
"at": "2026-10-15T15:30:25.359710+00:00",
"candidate": "B-final-fabf722bc8c6",
"C137_included": true,
"result": "activated",
"target_url": "https://portal-investidor.test",
"sources_verified": 36,
"staged_build_files_verified": 273,
"prior_build_assets_retained_verified": 767,
"only_missing_migration_installed": "2026_10_09_190000_prepare_investor_path",
"authenticated_actor": "Osmane Nala",
"INVESTOR_PATH_ENABLED": true,
"maintenance": false,
"existing_business_rows_preserved": true,
"COUNTRY02_and_other_env_settings_preserved": true,
"DevTools_configuration_preserved": true,
"accepted_criteria_repeated": 0,
"functional_acceptance": "12 closed, preserved",
"immutable_package_and_supplement_ZIP_integrity_reverified": true,
"backup_restore": {
"at": "2026-10-15T15:09:24+00:00",
"tables": 295,
"sequences": 31,
"files": 815,
"dump_sha256": "f234e33ce8498ac7def1764649b6ead9a1f94bbac6b1d9cda26f79535eff5278",
"files_sha256": "6e903c8d743c5a2dfe0dbee1cc113b52803411aecc037c09004b87e57d8f5d53"
},
"operational_browser_checks": [
"Authenticated installer: installed, configured, no pending migration",
"GET /investimentos: Os meus investimentos, empty state and preparation form rendered; no dossier created"
],
"limitations": [
"C137: technical evidence, no specific visual acceptance, accepted by Tempo.",
"Intermediate state without 190000: code inspection/prior evidence, no new HTTP trial, accepted by Tempo.",
"Line07 correction request nonspecific: documentary limitation accepted by Tempo.",
"curl local trust check did not establish HTTPS (000); operational opening confirmed in authenticated Edge without bypassing browser security."
],
"rollback": "Disable INVESTOR_PATH_ENABLED; restore 36 sources and prior build manifest/config from fresh private backup according to approved procedure. Retain new assets and schema/data; no down/drop or full database restore over subsequent use without reconciliation."
}
@@ -0,0 +1,13 @@
# Disponibilização B concluída — 15/10/2026
A Tempo autorizou a candidata `B-final-fabf722bc8c6` e o suplemento C137. Execução concluída no destino https://portal-investidor.test, com 36 fontes e compilação verificadas.
Backup/restauro fresco: 15:09:24 UTC; 295 tabelas, 31 sequências e 815 ficheiros verificados. A troca ocorreu em manutenção, encerrada antes de abrir o instalador. Apenas `2026_10_09_190000_prepare_investor_path` foi instalada, pela ação autenticada de Osmane Nala, às 15:27:09 UTC. O registo é único (batch 47). A configuração `INVESTOR_PATH_ENABLED=true` foi acrescentada às 15:28:01 UTC após verificação; as restantes linhas do ambiente foram preservadas byte a byte.
A interface confirma instalação e disponibilização configurada. `/investimentos` abre o percurso; nenhum dossier foi criado. A comparação por leitura das 295 tabelas confirma os dados de negócio anteriores preservados. Existem três acréscimos esperados: migration, versão publicada da definição e evento de auditoria. Cache e sessão variaram durante a operação. Nenhum dado QA foi importado.
Os 12 critérios aceites continuam encerrados. Mantêm-se as limitações aceites: linha 07 documental; C137 sem aceitação visual específica; estado intermédio avaliado por código e provas anteriores. Os recibos do instalador reconciliam as provas existentes com a candidata e o backup fresco, sem apresentar essa reconciliação como novo ensaio. COUNTRY02, restantes configurações e DevTools foram preservados.
Reversão: desabilitar o percurso, entrar em manutenção, restaurar as 36 fontes e os manifestos anteriores do backup privado identificado no recibo; sair de manutenção e verificar abertura. Preservar as colunas, definição, eventos e quaisquer novos dados. Não executar `down` nem restauro integral sobre utilização posterior sem reconciliação. O procedimento aprovado e o mapa de reversão continuam anexos na página privada.
A integridade dos dois ZIP autorizados foi novamente verificada localmente (SHA-256 e CRC), bem como fontes e recursos instalados. O recibo acompanha este resultado. O backup com credenciais e base permanece privado no computador; não foi anexado.
@@ -0,0 +1,105 @@
{
"base_assets_added_without_overwriting_candidate": [
"assets/PortalInvestidor-BgL6dTJ9.js",
"assets/administration-2WaaHIKU.js",
"assets/ai-DQrxdnH6.js",
"assets/analysis-CD4pUStB.js",
"assets/app-6koffaPt.js",
"assets/appearance-dMBBCbrF.js",
"assets/audit-IKTPV-c0.js",
"assets/bootstrap-confirmation-zU1pT5Kx.js",
"assets/business-D6sGcu4f.js",
"assets/business-interest-DMzRJKcE.js",
"assets/business-marketplace-16_YFmUF.js",
"assets/business-objects-DuARIRpa.js",
"assets/business-opportunity-BNbAOFL9.js",
"assets/business-verifications-2Al7Pg8m.js",
"assets/business-wizard-B2JTxZMO.js",
"assets/businesses-HEmaf_kQ.js",
"assets/case-B3iezsz3.js",
"assets/catalog-BwNtwLxB.js",
"assets/catalogue-BxoE4EAL.js",
"assets/catalogue-DNWlydH2.js",
"assets/catalogue-DzIlCfaf.js",
"assets/confirm-password-DoW48TlT.js",
"assets/context-BCjd3hOB.js",
"assets/conversation-Lbuxtg60.js",
"assets/convert-Cmif6Y0u.js",
"assets/dashboard-B7H-NvB6.js",
"assets/dashboard-Bv6vwdLI.js",
"assets/desk-internal-operations-BgotJDzO.js",
"assets/detail-lc1sZGLv.js",
"assets/detail-xVTgKqyJ.js",
"assets/dialog-BYzV5tSn.js",
"assets/document-BwUuCxkg.js",
"assets/editor-2DyDAvVU.js",
"assets/editor-4WTAzpYk.js",
"assets/editor-Czh8O56e.js",
"assets/education-DPfjwmlA.js",
"assets/fonts-C9MNnjVw.css",
"assets/forgot-password-NuXRKj0-.js",
"assets/form-BmewvnzL.js",
"assets/history-BD0biKsC.js",
"assets/install-BOKZXUPn.js",
"assets/installation-CZ_bcFXw.js",
"assets/installation-CuUS64JQ.js",
"assets/interactive-investment-map-kc25PBcM.js",
"assets/interest-Dx3i-rDY.js",
"assets/interests-DbjR9rUG.js",
"assets/investment-map-panel-D4UkHert.js",
"assets/investment-territory-Bj7E9cdW.js",
"assets/investor-B2RRfbRM.js",
"assets/investors-DO2PHXP6.js",
"assets/lead-BiFql0_x.js",
"assets/leads-DKvcU0F-.js",
"assets/login-pFhq8f0A.js",
"assets/manage-CEXfP-bD.js",
"assets/notifications-D7YtOqH-.js",
"assets/opportunities-BeP1nUjV.js",
"assets/opportunity-draft-DY2xk8f5.js",
"assets/opportunity-install-LOjhly-M.js",
"assets/opportunity-origin-P65CBahN.js",
"assets/opportunity-resources-f8hcGJe0.js",
"assets/panel-DwBN6cRB.js",
"assets/passkey-verify-CHbNONJw.js",
"assets/password-input-CZEiv6-Y.js",
"assets/portfolio-BeA7vA21.js",
"assets/profile-7FEFpszu.js",
"assets/profile-json-Bb5H6-rZ.js",
"assets/profile-kiqG9EDh.js",
"assets/references-a6GUerWr.js",
"assets/register-Dz4XuOsS.js",
"assets/relationship-repair-BbPpEIow.js",
"assets/request-BnuYhHmw.js",
"assets/request-DNLOT7Ur.js",
"assets/reset-password-FH2pmEDN.js",
"assets/result-BaPIoTbf.js",
"assets/room-DtK7QZt7.js",
"assets/security-B_oLYs5-.js",
"assets/services-BZQcAJGT.js",
"assets/shared-BEDl7WFV.js",
"assets/shared-CJucoqgO.js",
"assets/shared-CNf7SPwM.js",
"assets/shared-CXW4I9EU.js",
"assets/show-B3_nUTlb.js",
"assets/sources-DqLhX3mx.js",
"assets/structure-geography-D0mJ03tA.js",
"assets/structures-Bw3yjEkY.js",
"assets/submission-BztVPQOB.js",
"assets/territory-associations-BghnoFKh.js",
"assets/territory-geometry-import-BgUiqJjl.js",
"assets/territory-geometry-preview-DqO4V0-r.js",
"assets/two-factor-challenge-C-j2ixF_.js",
"assets/value-network-Bw5_SMDf.js",
"assets/verify-email-DGF0VDk6.js",
"assets/welcome-CPCJPF06.js",
"assets/workspace-Bo7B3eQ-.js",
"assets/workspace-CtTfcNTT.js",
"assets/zone-H5olHugq.js",
"assets/zone-attachments-CANe4XzA.js",
"assets/zone-map-DKg4YJ5O.js",
"assets/zone-relations-D-lZGYpC.js",
"assets/zones-PkKrJeXJ.js"
],
"candidate_unchanged": true
}
@@ -0,0 +1,22 @@
<?php
ini_set('zend.exception_ignore_args','1');
set_exception_handler(function(Throwable $e){fwrite(STDERR,'Destination preflight stopped: '.$e::class.' line '.$e->getLine().PHP_EOL);exit(1);});
$root=dirname(__DIR__,2);require $root.'/vendor/autoload.php';$app=require $root.'/bootstrap/app.php';
(new Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables)->bootstrap($app);(new Illuminate\Foundation\Bootstrap\LoadConfiguration)->bootstrap($app);
$c=config('database.connections.'.config('database.default'));
if($c['driver']!=='pgsql'||!empty($c['url'])||!in_array($c['host'],['127.0.0.1','localhost'])||(int)$c['port']!==5432||$c['database']!=='investemoz')throw new RuntimeException('Destination identity differs');
$pdo=new PDO('pgsql:host='.$c['host'].';port=5432;dbname=investemoz',$c['username'],$c['password'],[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]);$pdo->exec('BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY');
try {
$target=$pdo->query('SELECT current_database() AS database,inet_server_port() AS port')->fetch(PDO::FETCH_ASSOC);
if($target['database']!=='investemoz'||(int)$target['port']!==5432)throw new RuntimeException('Actual destination differs');
$input=json_decode(file_get_contents(__DIR__.'/B-final-inputs-20261015.json'),true,512,JSON_THROW_ON_ERROR);
$files=[];foreach($input['source_files']as$n=>$hash){$p=$root.'/'.$n;$files[$n]=['exists'=>is_file($p),'destination_sha256'=>is_file($p)?hash_file('sha256',$p):null,'candidate_sha256'=>$hash,'replace_required'=>!is_file($p)||hash_file('sha256',$p)!==$hash];}
$build=[];$dir=$root.'/public/build';$it=new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir,FilesystemIterator::SKIP_DOTS));foreach($it as$f)if($f->isFile()){$rel=str_replace('\\','/',substr($f->getPathname(),strlen($dir)+1));$build[$rel]=hash_file('sha256',$f->getPathname());}ksort($build);
$schema=$pdo->query("SELECT table_schema,table_name,column_name,ordinal_position,data_type,udt_name,is_nullable,column_default FROM information_schema.columns WHERE table_schema='public' ORDER BY table_name,ordinal_position")->fetchAll(PDO::FETCH_ASSOC);
$migrations=$pdo->query('SELECT migration,batch FROM migrations ORDER BY migration')->fetchAll(PDO::FETCH_ASSOC);
$flags=[];foreach(Dotenv\Dotenv::parse(file_get_contents($root.'/.env'))as$k=>$v)if(preg_match('/^(?:PORTAL|INVESTMOZ|COUNTRY).*?(?:ENABLED|RESTORE|RESTORATION|SHARING|WORKFLOW|PROFILE)/',$k)&&in_array(strtolower((string)$v),['true','false','0','1'],true))$flags[$k]=$v;
$protected=[];foreach(['.env','config/inertia.php','bootstrap/app.php','bootstrap/providers.php','composer.json','composer.lock','package.json','package-lock.json','vendor/composer/installed.json','public/index.php']as$n)if(is_file($root.'/'.$n))$protected[$n]=hash_file('sha256',$root.'/'.$n);
$p=['at'=>gmdate('c'),'candidate'=>'B-final-fabf722bc8c6','destination_root'=>$root,'target'=>$target,'SQL_read_only'=>true,'application_url'=>config('app.url'),'PHP_CLI'=>PHP_VERSION,'config_cached'=>$app->configurationIsCached(),'route_cache_exists'=>is_file($root.'/bootstrap/cache/routes-v7.php'),'sources'=>$files,'current_build_files'=>$build,'protected_configuration_and_dependencies'=>$protected,'boolean_flags_preserved'=>$flags,'inertia_devtools_enabled'=>config('inertia.devtools.enabled'),'schema_sha256'=>hash('sha256',json_encode($schema,JSON_THROW_ON_ERROR)),'schema_columns'=>$schema,'migrations_sha256'=>hash('sha256',json_encode($migrations,JSON_THROW_ON_ERROR)),'migration_count'=>count($migrations),'destination_business_data_read'=>false,'source_writes'=>0,'active_changes'=>0,'activation_authorized'=>false];
file_put_contents(__DIR__.'/B-destination-preflight-readonly-20261015.json',json_encode($p,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_THROW_ON_ERROR).PHP_EOL);
echo json_encode(['target'=>$target,'URL'=>$p['application_url'],'sources'=>count($files),'build_files'=>count($build),'migrations'=>count($migrations),'config_cached'=>$p['config_cached'],'devtools'=>$p['inertia_devtools_enabled'],'active_changes'=>0]);
}finally{$pdo->exec('ROLLBACK');}
@@ -0,0 +1,12 @@
{
"ZIP": "C:\\laragon\\www\\portal-investidor\\outputs\\investmoz-audit-current-20261012\\investmoz-documentos-decisao-Tempo-20261015.zip",
"SHA256": "ad80bfceec77ea651214921684ff827c78573a1604b0cd9da729aabd4a97e9ea",
"files": {
"PROCEDIMENTO-EXATO.md": "92846634655beb75259e0e2b5817883212bc028cce851c42bea9fa43c860bf7a",
"PROPOSTA-UNICA-TEMPO.md": "62baeee94807c4fe67d1e8d7178b8dc9e78b323b4d73b622eea4228d6a291c2d",
"RECIBO-INTEGRIDADE.json": "3731b48860c5d5729459141bd92119264f2940e932aaecde6cb657cf32b333b4"
},
"CRC_and_content_hashes_verified": true,
"candidate_unchanged": true,
"activation_authorized": false
}
@@ -0,0 +1,7 @@
import pathlib,json,hashlib,re,datetime
r=pathlib.Path.cwd();o=r/'outputs/investmoz-audit-current-20261012'; p=r/'.env'; b=json.loads((o/'B-activation-fresh-backup-20261015.json').read_text(encoding='utf-8-sig')); previous=pathlib.Path(b['private_directory'])/'files/.env'; installed=json.loads((o/'B-activation-installed-20261015.json').read_text());assert installed['installed'] and installed['pending_migrations']==[] and not installed['path_enabled']
a=p.read_bytes(); assert a==previous.read_bytes(),'Environment changed outside window'; assert not re.search(rb'(?m)^INVESTOR_PATH_ENABLED=',a),'Explicit setting already exists'
suffix=(b'' if a.endswith(b'\n') else b'\r\n')+b'INVESTOR_PATH_ENABLED=true\r\n';changed=a+suffix;assert changed[:-len(suffix)]==a
with p.open('r+b')as f:f.write(changed);f.truncate()
receipt={'at':datetime.datetime.now(datetime.timezone.utc).isoformat(),'setting':'INVESTOR_PATH_ENABLED','before':False,'after':True,'only_one_setting_added':True,'before_was_default_false':True,'env_before_sha256':hashlib.sha256(a).hexdigest(),'env_after_sha256':hashlib.sha256(changed).hexdigest(),'installed_evidence_sha256':hashlib.sha256((o/'B-activation-installed-20261015.json').read_bytes()).hexdigest(),'credentials_COUNTRY02_and_other_settings_preserved':True}
(o/'B-activation-flag-20261015.json').write_text(json.dumps(receipt,indent=2)+'\n');print(json.dumps(receipt))
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,28 @@
{
"at": "2026-10-15T12:47:52+00:00",
"source": {
"database": "stability_consumers_20261011_084534_test",
"port": 55441
},
"restore": {
"database": "b_final_restore_20261015_124723_test",
"port": 55441
},
"database_restore_verified": true,
"all_table_rows_hashes_equal": true,
"table_count": 295,
"sequence_count": 31,
"sequences_equal": true,
"candidate_source_and_build_files_restored": 208,
"file_restore_hashes_equal": true,
"existing_document_files_copied_and_restored": 133,
"preexisting_unavailable_document_count": 0,
"private_dump_sha256": "43e02a2ec28cb4eb615b1b6ff7c97590378b3dd5b8585ce00bcdcf00e89a9e13",
"private_recovery_directory": "C:\/Users\/macbook\/.config\/investmoz\/B-final-recovery-20261015_124723",
"dump_credentials_runtime_config_not_in_review_ZIP": true,
"application_boot_in_restored_database_executed": false,
"functional_tests_repeated": false,
"QA_source_writes": 0,
"active_changes": 0,
"activation_authorized": false
}
@@ -0,0 +1,254 @@
{
"base_revision": "396c691930bc",
"source_files": {
"app/Http/Middleware/HandleInertiaRequests.php": "e117d366ce411944fd560b5b8117853859532e255bff5e732f1874a1eac70979",
"app/Services/OpportunityCanonicalContract.php": "cf16600559fd3b6afb660845ee5e2360a63c4915ae9de5297803c53afda4f617",
"app/Services/OpportunityProfileWorkflow.php": "1d05a8e445c421364a534323e447b8cff84be2254d5f335ef1a1a4a2b18fe365",
"app/Services/InvestorPath.php": "7734420bfe2fcee0e49a3ca759987d54877844afb68bbba0f2a6ec3d1ec33269",
"app/Http/Controllers/LandAssistanceController.php": "3177919b63517064d36f977b7f779bd4d7061329c98c8b3710978c179a420031",
"resources/js/pages/land-assistance/form.tsx": "f9357ac8797ac2a0ba8d9a2022fb5c466d8afc55c57ed02deb144f1bf582f6cf",
"app/Http/Controllers/ExistingBusinessController.php": "ab085d31582b93c913fd5f0657c557b8f1d893cfb557a52302894a0f05956e7d",
"app/Services/CountryCatalogue.php": "fc0561dd0ee0e4c8340450892fcfb1c8678a7dd420428c60eb3890b2d82d9312",
"resources/js/pages/investment/business-interest.tsx": "2785ebeba2a4756f029514cb4ca2a6d8b312d2c292b5b71e2761b431c3e3dc7c",
"app/Services/OpportunityContacts.php": "d186abf83a959069c61b837a2424ce78719286e32d94672e3eedbe46f419121a",
"app/Services/OpportunityResources.php": "21adfc77be4810576b64e07d4d1c1adef69ea6d34f0b67d959631593fe8282b2",
"app/Services/ExistingBusinessIntake.php": "3ef03e137ff8241b2bd3ea64e00a0006de68ac20703edbbbb06d2837d09cbd1e",
"app/Services/InvestmentCatalogue.php": "948c9b78f892665700ed324d6e1ac92b591735f120236d86b13b58a1db39d0d5",
"app/Http/Controllers/PortalManagementController.php": "f03dd52e6072d2f745a1ed8ab6725a93182281c1e5cb507ed31c7e017cecb878",
"app/Services/OpportunityCategoryFields.php": "f452092648f673a672277b2234294348e3ad9a1a601aa493bcac01851a5d9558",
"resources/js/pages/investor-path/show.tsx": "db861e5e3a850ee571fda0299cefc4451edbf7ac373ee0d811c73d2d62539284",
"app/Policies/ExistingBusinessPolicy.php": "f06f3f3a9676e8659ee9e21c4fd04610f4f44664f692ccd7307b6c697bee9d4d",
"resources/js/pages/investment/shared.tsx": "d40eac734af27c4bb79f3a968da18a909d26c5890795508dda4f1180b0aa5ecb",
"resources/js/pages/investment/catalogue.tsx": "99707526863691eeef0d3c7971b6a3399d193f8e9fc2ade25ce1dbf2fd866b11",
"app/Models/Opportunity.php": "db3ed93d14040c55888eee7f13d1e3eadd4cae5786ff525b03cf77a56f712dd2",
"resources/js/pages/investment/detail.tsx": "048c70bb3fa9671721d2a0c0361935df5336c39e46b2d71bb16de29e25d5dd88",
"resources/js/components/opportunity-canonical-fields.tsx": "ca5f07627707f0a7a75ea1c7e3fed9bb8381917a07e85d6401242c9f2d87d9eb",
"app/Services/InvestmentRelations.php": "436e2e0e886741ee7e6440a447566f5c1ab0e9cad7e8fc88d298a5682bc2b92f",
"app/Http/Requests/StoreLandAssistanceCaseRequest.php": "2b3f24698e98f7262dfdd1df963ae8cf0f347f3b338c072e3d8f524c05c49ce4",
"resources/js/components/portal-grouped-menu.tsx": "a9ff5bc1ef0126f67a0f00cc13dd3fe087af98a0bfad5feb3cb8fe13214901a3",
"resources/js/pages/land-assistance/case.tsx": "ea1937b9ee8ea641ecbcff588ebea06c8aac59762c9f800b11bdf908f69b54d9",
"routes/land-assistance.php": "76522b6b78ab1a0319605aea5b57cca188e60a09ec2b5a6af4930ffb464b2410",
"app/Services/OpportunityReviewMateriality.php": "afcf465a51a7dab1ff9f50d41243407b5e9d83aeb85fb5ef0af3ebacdf9b7eaf",
"resources/js/lib/portal-navigation.ts": "fc2a4986eb48795024e8501983ce35f8fa772198be911183b329ccafb888ec62",
"resources/js/components/opportunity-profile-actions.tsx": "ae26baa8aa60b4c6c20093a332c4d26644a67ee0ab3e511c995ea7327133bb44",
"resources/js/pages/management/opportunity-draft.tsx": "4b6acdc5565f8c357fb3df6ed3cbae905b52cf908008479aa4f00593ce5dc8c3",
"resources/js/lib/profile-json.ts": "fdf04c41e4e6e4e2b9efd3ffb0e5cbc9c91fc281fd99caf63a6e64652ca5b69c",
"app/Http/Controllers/OpportunityManagementController.php": "a7ab08036d869d568c1a38d82c37cf94574881a322882c772e0ac6d16ac4c4d0",
"resources/js/pages/investment/business-wizard.tsx": "e97086260bee631f3a5a0f78535ed8e9664597bfb1d9a44af8e9ff6872271c5c",
"resources/js/pages/investment/business.tsx": "8d209da93ae09347113e21dde44e60fbe620525401170f60b19064556cbe2ca2"
},
"build_files": {
"assets/PortalInvestidor-B1b3WKdU.js": "6ac4dc4aaf0c0818cb65f5c41fbe904d03a477ddc45cee9782619d233a5828eb",
"assets/administration-4iX3lyfJ.js": "ab0c0f48de5c3be23483a6c359dfba6cf547aee25f98a79831a30f98c3f6ebfe",
"assets/ai-C1AwaRj6.js": "0082e70fe18868cf2faea43a36c90da7225749cb79db0707e17b5a59af1df7ea",
"assets/analysis-Buws7paD.js": "c4944d719bab7256b19ea954b831f00c00bfae5db2d753bf0c369592cd5d29b5",
"assets/app-_QxUM8Uv.js": "a607c36d74312ecdde232b1bc92876f98335cca64dfbbcf23816915f6c3bf6d5",
"assets/app-kj8h1utZ.css": "4cfedaf0837b8be29cb1c98095251168d2564ef199a290b336f9126cbbbb15aa",
"assets/appearance-Cc2zP-Sd.js": "63a9ce48dea2a5a9a84ea0d6a3b04abcb84fc3bd92ea9a6835efb53c242d2a24",
"assets/audit-BVplYILe.js": "6414ac9ee8eacf8de18c64de37c698f629208d93bfca225cd5f5dc927c9b6c74",
"assets/blank-2jFZEe2q.js": "9e53a0a455027f070e3041db1f445e8b63702f83e264442d8df87e20048ccbe9",
"assets/bootstrap-confirmation-Bjm845T7.js": "b001d46f219d99f71844592c8a035fba1dbfaf7bee9a8ea2a1ccd0c3b0f9c78e",
"assets/business-Dx-g9F1l.js": "9b5f5027c8f5f2222d89598c1879dc5c1acf9c473b5cbefe62c93d5d9735bbb2",
"assets/business-interest-DwzIH9cJ.js": "a2966fa146ac153e676264af7727e9fea1952eb811e5c8b00f469914ae124fe2",
"assets/business-marketplace-Bha1dEfr.js": "93197ca0684233cb6a2306102cab5728326661c21abeb7de3a5b1600d19debaa",
"assets/business-objects-BRSsWpdD.js": "ef2437b17e91effc5bd1e0749d56b0776a0aabecc8b07e8107a04307926587f2",
"assets/business-opportunity-DNToO3uL.js": "057572bbbcccd6656df4fe1241ae18f021f88d71b0e63e67f3660771f2d6e9a1",
"assets/business-types-SGCXhH6X.js": "c792ab88a79f57c74d865c47e89e7f2b9aea190acb5c8c676071d4b0a802d58c",
"assets/business-verifications-Xydae-ss.js": "18aa7fe1dd6889f7a27dca929dcc91c28ad1c5653b54646c4ccb75fa68bb36c8",
"assets/business-wizard-CweTzeAm.js": "0befba10184e234dfca2ad13df2b3ca0f4e0fa145dd1eedef80ae742a5c440c3",
"assets/businesses-QPzv94h1.js": "0d305802bdb658fc64950e64052837b652cfd79858ac1a5f0d2b84902c385aa3",
"assets/button-DAU4R6e9.js": "79b615d0b88db74491fb4b312ae70515d43332e8730f8baed64c81eec510171d",
"assets/case-B7a3k3tp.js": "b36c50ad695e6aa82e6a83286d3db63b2c445d853fe97998a5f544834b9a5877",
"assets/case-jhW1p_fJ.js": "c153137a1a70624ffa79a821afdd67e4589ba17d7a63eca3cbe7bb1fdae087a0",
"assets/catalog-DfcqZxWM.js": "7108d4b6aa8a7ca044326b5dee2406bec21b6d5745793a9f94806696cbcc3374",
"assets/catalogue-BmxB6oqs.js": "f51e72f15c0b44b5550ea1d2cbcac1f441c68cb5743e074f3bb7b18180f97820",
"assets/catalogue-CyaEXEUk.js": "5cb46f45e6c3def141ba5135a659074530b77037b1db0970f8d6dd1da4972f72",
"assets/catalogue-Zy33X5RY.js": "da51ece41579197eabb3dce58fb3ef6bf329fb1e32f597cc81b0ea1112597db5",
"assets/check-PcBNn_NG.js": "402150a0f6387f9f098fea689a3282723ee063c84e57651f25d35729cdd85063",
"assets/compiler-runtime-sKsOXjDo.js": "cc5f3db4bfb3bc5ae09b4594e5e137ad20037e8dfc3f0791781665706b860b6d",
"assets/confirm-Culw9Q-x.js": "263fd058f1562c5729a4091d5d60f5365cc3957ad2cfcb5ffdec04a28f1858c4",
"assets/confirm-password-DOsJGE-_.js": "946b55b8f8e2ec72b1060c08987968df5f12b3e39cdeef2077e6863f2acc3e45",
"assets/context-ChrStmRt.js": "96b8f6c034ad322e008f4f04beda59e7d2025c591cc9a1eb99970e8493f0756d",
"assets/conversation-CVySJ5Os.js": "b5d3de7fcb3e2ebf32e175408749e1d449fb9c0b4cc87e42b96d3bce3b5ddc37",
"assets/convert-CFqWFsBC.js": "11f2952633b162e89252332d059770aced88bff38ebcd091efba5fde95b17750",
"assets/country-select-C3BLoPPG.js": "87822f75957659509b95011d1489f6bed2ff824c215fce862a7fd29186f5189f",
"assets/createLucideIcon-oMeAlXbs.js": "9398e5f9d8be91b886b9f6283574d6eb89b8fa02a4c21866ab9e376c95b74b56",
"assets/dashboard-BvCddPdb.js": "220edec3916717bf649036bf3e2c13963d42321bfb3dde3380cb5701b84d5318",
"assets/dashboard-C2C8-DQM.js": "783aa734af9d3fec5cce33c6cd0c3ab58eb101217ecc1c588850a6c105484474",
"assets/desk-internal-operations-ynG9LTO4.js": "21abf9d8fb90fd949112ca762d0432d808507884d60ccf4611649eeab5bc1b30",
"assets/detail-BIfHtFTv.js": "feab3b614a03666b0a1cdd30bdd06b40caae36123a1ac3fba4424adbe2a9ee9f",
"assets/detail-MMkJ03oN.js": "0b10fbc173898da661c368c7c3a495768af28a3e10acea892527275ba605cd36",
"assets/dialog-DUS-YcSD.js": "17aee9d2ff92dd60900e0af15a7145447b158cc527d9faebc6b1cc8ad4f1d85a",
"assets/display-value-DRR1EAAK.js": "202c77561454ec7c1ef9cb39faa4f1833ea066dbb83e17f0eb4440b314b189f6",
"assets/dist-BRfsww6z.js": "1b5218b53553fd01fd50cb0ce2102864c5359d450d4d71f00806f812f1e1870a",
"assets/dist-DDq_DSJX.js": "0ea9c4863c02cabf343ba678aa470b682ef3ae1588380bee5b0781d356e9ba46",
"assets/dist-Ddn_hEUd.js": "ee0c56af5abd78d01704f2fb0f764ea0746908244078a8014393a672994235d6",
"assets/document-BHIjQVsT.js": "f4e6d30a623efb932b0905bc70e6bd1e8da71bb542ac5f540b5c063f49a75e92",
"assets/editor-CPltGApx.js": "abb8a68c5dad1c633bc20b3b1123e710d8b9cbac1078fa36087835eadc13e834",
"assets/editor-CzCsyqfx.js": "936571916e0cc3815b622772049ae5954f4389d4774de0bb60cf654b58c7850c",
"assets/editor-Vvw00b7m.js": "4744f5ca169c2b20fe3a74b1ba732ab21fece3efe144139350f56a48794ad78d",
"assets/education-CoSzu2ss.js": "45d98fe8a14254915f022ed6042eb8f419e7f8cb976db134a10c9ab86842e127",
"assets/financial-calculators-CsDOUJxx.js": "e76679a1914b5c4dc6c3e74b1b2de8d3d792fcc891dcc61d0fa27042232e2b9a",
"assets/fonts-DmGVJ3xF.css": "0d8ae8a842951a087a04abd66fd137a310b819bbf335c0fa9e2d4f615981f231",
"assets/forgot-password-Brr18zQf.js": "0d1e4b67ff4a1719a516b2ac9c641c9fbb5e7d49c11bfe43f08c5d0e67560c72",
"assets/form-DRfnkICL.js": "23c6ffdbe43f2fedc8e5405cf23ba83bcaabf3b61555e2078a23a9d3b258ff40",
"assets/guide-mndEuKFT.js": "fe519ab69363e83bb705b7dee5ab3fe17249eeb53687846b539668c435ccbd2b",
"assets/history-DEIq0T_f.js": "2dbddbc18db118170c29846a011f3c99317f627bb4bfdfd9b8e55bce49564a76",
"assets/input-error-U1QKS0ED.js": "4acac92fa624552b14ac1a390e961f9e387d6eefeac384ad4e95bc73fdffa86e",
"assets/install-C1r0bHiP.js": "7dcc06d66028c74ef8675d59a881c57f5bc21f71b6c61487b245403fb6c83fa3",
"assets/installation-CEmL5By5.js": "a70c2a928b9a09d91585e03d308bf72e0e28a57de8a5eec8c42e20feba7719cf",
"assets/installation-MMDaFe6E.js": "619e1b4200c983ab6931430da924cdfe8fc795f132da84e234fb7ba0a41bc0e1",
"assets/instrument-sans-400-normal-D1W7dsQl.woff": "797bd3eaa70edbd4757650ab44dad75fbfbfdf18bacedb4b71022c04621d30ad",
"assets/instrument-sans-400-normal-DRC__1Mx.woff2": "9a91efaa3599a6ef01b2f49e9ec670e3a2f39baeef09c73198f1052cf3bb0850",
"assets/instrument-sans-500-normal-Dk9ku72i.woff2": "9d3547da16d950d12a677c772a3ff9b69846e60e7dcd1b5efd540993f7286532",
"assets/instrument-sans-500-normal-Z6ESRlEs.woff": "bd6a8dc8b0dc0cced0c32d3eda93f0e0e82c58ddefea8b53b3307b0c48da3089",
"assets/instrument-sans-600-normal-B7fBEWYG.woff2": "efb770916eda95a0e31d80cccde9651d4e8617010b21220e9f227c4820d675da",
"assets/instrument-sans-600-normal-B9e8oLYv.woff": "9b4ce1f2b26be7cb087fd87d6f99a202136292ec820af75bd38ab9e53895cf28",
"assets/interactive-investment-map-1DTFk8zz.css": "13748a8189dc8c690fc902a1682d30ba289721688f32df4f2459a36de8e383de",
"assets/interactive-investment-map-BwEIJoHZ.js": "b1a160459acf33e808f203e9276dbe1e8bd4622c086e6640eb4e623617fbf723",
"assets/interest-De1GJygr.js": "0435419f91390868d4f5cd41086bf0775efcb02a261b3bb31de410e9f7142a04",
"assets/interests-Bux6HtO3.js": "e42608e51365f0b33960a790471f2c8ec9e94b36c3556c0c1bc37e1dfe5bf5a8",
"assets/investment-map-panel-DPH5OZg7.js": "9d006f2c44fc33f521cfab147a452e41841b7002e3ea4f05bc8bcb0dc3b5f0ed",
"assets/investment-maturity-CydhhEfV.js": "c2cc75070cb664ab0b53466dde584dd5473f1b5fd992bf6a59ca8a01b7e19623",
"assets/investment-territory-CZryDFzG.js": "7087d273189a222d409a541d195dcca7ba60eb3bd71b57b2b1fd56a03ff9176d",
"assets/investor-CF8sXB4I.js": "78e68c79ebe2f2bc9fa956209cba8d0c503d2f6e5dc00bcc268df76db96e1734",
"assets/investor-path-CAHGk6qB.js": "d097b941ba9393ef82351cbd6c1b3e96d17cc3a7d605e721a2ef282557db8422",
"assets/investors-BCSy92l-.js": "df637813d1dc8b4b335b554f4001a6e231896b63a2b2e8644ffcbe4cea990b9e",
"assets/jsx-runtime-BpzPEenQ.js": "60a64ced602d5e913f2a0328d2ec4a7b670c893614a26c47794317523d276398",
"assets/label-D-C_NQs4.js": "6b4996b6f05276fd6edc8dd935f37f83a6c673cad5cf2f9dfa7cf4bdc92816ef",
"assets/labels-DxqjesIG.js": "deace12e77e3f2e0515b1090cbc376cfeff29b59f57b1a2561b1145459c531b8",
"assets/layers-2x-Bpkbi35X.png": "066daca850d8ffbef007af00b06eac0015728dee279c51f3cb6c716df7c42edf",
"assets/layers-BWBAp2CZ.png": "1dbbe9d028e292f36fcba8f8b3a28d5e8932754fc2215b9ac69e4cdecf5107c6",
"assets/lead-Dw_nrk5k.js": "410a12aba24ccdf46e67967bfd3dda66ba384dd79f4f28776d6dca56263db102",
"assets/leads-6RFlgHCo.js": "c289a541ff49b81127aa2f6d9b38f188a16da0343d4e976e03f35286f4986b4f",
"assets/leaflet-src-CUWrUTR2.js": "a26eda55b9706e8778766e4d32038202d20411081d7da16faaa39b977af36245",
"assets/legacy-CX8Pcqkj.js": "977cb3622e6ab01bf0a83421e8ce7e998b98755e18cef18e83db6238b3e29f33",
"assets/loader-circle-DS8Tf4er.js": "cd9fb22e9d7d12342d5e0941aac953ebb5184550cc8008b5c0f8f5ea6acd8ed2",
"assets/login-DHiqnqsd.js": "a4734957fe29c65d3121cb531dcbec2384ff3ea91a124612bb9074b133e7100d",
"assets/manage-BHwgBS--.js": "8901ba04d0de89650751472528270024be355bdab4317912e39db69d73ad2b18",
"assets/management-CvdeRZYq.js": "0c193b26e40abae535aa6b51d1734bd930e4d2570dd0033cf0b41efc47aa16cd",
"assets/management-access-Dl70YCx1.js": "1d50024d467e7f6fa4be11cca48534b0b697520cf894282b33ba33cc95db026d",
"assets/marker-icon-hN30_KVU.png": "574c3a5cca85f4114085b6841596d62f00d7c892c7b03f28cbfa301deb1dc437",
"assets/notifications-B-eLBfv_.js": "4e876806a4df82a644c7adab83c050761ba830ade7f05fdc70aa602955e569de",
"assets/noto-sans-400-normal-BTkUljjl.woff2": "09aee8065d25508f23a4c3d92cd777ac869c52d93fd868a88f025d888a7937d6",
"assets/noto-sans-400-normal-DPpKfCgK.woff": "18e2e5b23a9bc5e8e636d6c7984b8ac6635aefc1c497ed1c5012f3c637761b91",
"assets/noto-sans-500-normal-CDPngY5C.woff": "15f5a154b97262907900b5e3d297333417396cc775ae2e73f801763ebbac1dd6",
"assets/noto-sans-500-normal-DCA2Z9Cj.woff2": "1d35aaecc5c7a375d87c12787e1e4c5d6a695315b757e1e18a479d1a2f84e973",
"assets/noto-sans-600-normal-DVJMj_t0.woff": "954cd3f8c324a52a0a78a97a48f459a6656400a814e427d2ef62a680b83d82b8",
"assets/noto-sans-600-normal-Dkgu5AE5.woff2": "79e274470d1c5a0118eb325e2ea6f2eb2a449336d7fde1a4f20a2f32fe1119ed",
"assets/noto-sans-700-normal-CrvTEWhy.woff2": "e77bfe1db912f687b0319b60de158cfada67f89c8ee4f8e2bd6020f970accbfb",
"assets/noto-sans-700-normal-ZyrKABVF.woff": "cac2e44ebc446d5c71a9a16fd5592bf80abf6f56dd564a7b90eb01c5f9d29793",
"assets/noto-serif-400-normal-BV_iYGc9.woff2": "4c0cbe3eec50d260754d681c17ee2af49a43d7fd93ce42877f665fcb1a889b87",
"assets/noto-serif-400-normal-DT0cwSa_.woff": "084719f02390eba8960814e1845fba7e6857d63895f53fe8321bcac6b4c73d40",
"assets/noto-serif-600-normal-BiuDA9L7.woff2": "abf0abc765331d7a1bbe6eb3603cf86be1cf3d1edbcf911cc2d52f78998c02d9",
"assets/noto-serif-600-normal-RZopCp-J.woff": "a8b4433851ac750477a973bd493289e4df7c45072c6a66b08354d9796d42d405",
"assets/noto-serif-700-normal-CIw17UNa.woff2": "0d0b440760c93e6fec440ad438d10cea6c70367a0f5ecfcfa15cef0a85c67093",
"assets/noto-serif-700-normal-mX-AlFMT.woff": "7057093244f719a3fd3706e9d1941b4161941ffcce81ecc661bc93644bbbd6df",
"assets/operation-key-Dr4VtGxa.js": "416fed7a5197657971af7f378998557c9dba2f99e266e39149b727e598bea439",
"assets/opportunities-BvUjkGMA.js": "d4dfb34c38195927827b82c5fac238ff83f6cfc4134f1920b269386eff170f63",
"assets/opportunity-draft-CY3-taid.js": "838d95f7b2e1898e72067a9abea9f28d835c35e5938920303676588aac107450",
"assets/opportunity-install-BEeEaRIi.js": "cdc518eb8cea7eb51b9bf97b7fc390028d5843582f0ad55c781a285efe60ae3a",
"assets/opportunity-origin-BieMJONP.js": "2277daeb0abf2b1f7a22b419f4c531073585927a6677c18488e004292c096b54",
"assets/opportunity-resources-C4bqMI-S.js": "a4d04b314c11547788ffc65969bc9ed80ca2ae7ca5458dc5b2124a79da835749",
"assets/panel-MPfKo4Gs.js": "38cffc866958033430f42c333e596499317f03202d36903f216b664921c70fcb",
"assets/partnership-source-links-VfrXk2FZ.js": "a4d6c8500f2417983312ae667b96f035df9654f37aa4a7bc86f0cc01fda0ddd8",
"assets/passkey-verify-BHwbYqlV.js": "da94d9b76d9e8fd23e283b1b935ac2c8bd1649b31a35bee21b32a3b37a16ac49",
"assets/password-CB_NxgQN.js": "4415e495723009fc084111bafd2b7714221a3712e5f1d2a4dfa0e698f6308c7a",
"assets/password-input-Bvqo4Od7.js": "8ffa0ccb49a05dc8198fe43cf051664426e493c64f8e6d982e2317754c3963bd",
"assets/portal-api-tEuwFTsU.js": "190505d0a96d610ef2893cf06c63edab30f427593452bbc0dafc9d8f8a826c70",
"assets/portfolio-vrkKu9n-.js": "8ae72ba25132620661e3b3d498164b66b429d1d1818d9d1085dc7413b0bf9830",
"assets/print-EIzSB6Ku.js": "bad87486159deb855589aa92fc7032ea28de222693c2816f2ff54b1583ef6513",
"assets/profile-Df7SjInW.js": "8a56cd5a0a41e48c5ba745b1341c2693ec197da68d9da677431bf538ffcf6ae0",
"assets/profile-json-BC1mQPe5.js": "269ee0efeb8b9b9e175e6e23e553b5b11b0dd8bdffdde3a99b76427c900dfa2a",
"assets/profile-mFQ94cGy.js": "541f7cd906d76228aa3e6fa6d1f4ba81d5b13d96c94fdf034d26e9bebd228094",
"assets/project-dossier-BRpAqBvm.js": "9906a87fcb5b99bea2eca25e68dc49c149c7b250056a8ac0977d2c8b6cf4e732",
"assets/react-CjVep8xp.js": "3378f8538b0d8c51e3051e5005dfaebb8fec48c35789a3ba63945fd724f48e6f",
"assets/references-Q3ObwDEu.js": "d57e87de9dda81699395e08fbee7d184ed8b735813f77a78e2020315fffc8795",
"assets/register-CRijmNdY.js": "3d3792812483909770637d9b14196b72cf1d8dd42970e7939c7580c8c04863d8",
"assets/relationship-repair-NfFTKlpn.js": "afc77703d8e6cc61ab5a52ad3c1487147ac7f848788d64cd08cd969ca1a65e91",
"assets/request-CF7xQbtn.js": "61c4f9d5902ac8b56fd5ab0fc6cc9adafaf02c65d1a35af42a4c7e4ec16f8304",
"assets/request-Dzpl-g3h.js": "db18a1ff9d24555fd2b8d177667d23aed7ec098ce88df5f98621bcffb6551ba8",
"assets/reset-password-D3X50aA5.js": "cedc09fc514819a0c71a03e8d7f98380cf61a262b4319d748151bbb0c1fb43e0",
"assets/result-DoL7QLi4.js": "207d07c1a26ebced6e4627cda5f51bf498f3253fad3a17c085ba5cd3dfbf7f4e",
"assets/rolldown-runtime-Dd_uD5pT.js": "c5f0356f5d0918a3137e4e811fd18950efe8ac8f6bf84d1d4da7811c477a24d8",
"assets/room-LM3pUYAr.js": "5130e9b6f98698568d847588656815fd3a3a6aa38cbdaf0bcd822d96c539c0be",
"assets/security-CP6MMYJw.js": "01d3cf8af26a551331127800c9fbd8cd11d84418e82bd0e16c5a64c6f8d2dc1b",
"assets/services-CoqWEvPN.js": "03138af66477bb90f6a3262c21857f07d2a35bec8471b1379d7be8d53b836bd7",
"assets/shared-Bi0ozaSH.js": "37d1064bf72af9e5a1519a9d3c82cda900fb6b3d1bb520b2b2620072a1370708",
"assets/shared-C9SLMUlq.js": "1c9ba92a57a273580276985ce49a25e7572427f3717a7c83a9f6f4360fdfca60",
"assets/shared-CBz2_oAS.js": "9898ea7fc094a14fa73562de02d2ffe8ac99c59ab381737a595c6d06292234eb",
"assets/shared-D5bkan45.js": "edac9c0c5425bf770e901bbd3ac05f00a01c75d430743c1450c472ed9a46d7f7",
"assets/show-CRx_Kgt0.js": "04324820e5182cf56e7ec74ee447ee14d7cbffd1d08e8720622e37cdcbe8b3c6",
"assets/show-DcySP7EF.js": "a2e815f7891c9867c0ff43267a08385e89ebe9e2842114481e2623bd018fe51d",
"assets/sources-BD4xHxsm.js": "37be260d600ad04c08626d4cfeee0816598957aad2256c5c3feb899bb76f55e3",
"assets/spinner-hD8hHC_m.js": "0091bbe0e4125cbe30ecd10ec9ff65cff9b7bd270125913d85b4449144aa91fd",
"assets/structure-geography-DjJYBqm1.js": "1d2635db51184c0e73fa77d201a7401189947b28f6f35e790a5307a252af666b",
"assets/structures-BEUCF3vT.js": "92adc457e8f8c22c86ac68fdc2617fd945c49ea74c3614c35eb85807b48c9688",
"assets/submission-Bb710thW.js": "cee8933a4dbff12783634d2f274b8dae4a7544600383ecd46b07d6a7752ce53a",
"assets/territorial-source-evidence-eKB4ZB36.js": "14048631c51933a0389cea37ae1909a02ea86d564a5a05452a48b40f055cd605",
"assets/territory-associations-DQCywWbt.js": "bb368b3e78fe144262fd04b749652845c634ee70b69f4c27bd3a1175c5831fdc",
"assets/territory-geometry-import-bSp4-HnZ.js": "c2a5109f7ac841637eae5b5fbc396304f846f438ff4ec3542ed047517e9c62a4",
"assets/territory-geometry-preview-Co-tMRm3.js": "5dcefaf9e586a7cea516fac17a901a3a42f0e5a2218347ec4a006a64b52a0f0e",
"assets/text-link-BBvcP60s.js": "0e7b5234d766855dbcbd5a78fe3e8c54fa6ffa1ad6163009d7b312eafd19f307",
"assets/two-factor-challenge-DzymIfIc.js": "0b2ee71512d1ffc112489a5eb8257bb4c9ed0382c74ce6edb6c1f13ffa4f153c",
"assets/types-BoD_IJFv.js": "75c4a127c1aa0b90fe0b4f956c7e3ae9c67bc0f862c89cd0a594709027b983da",
"assets/types-Cxp_Nskt.js": "cf4ae8cb539c697ca751dcf96e1db3af9eb1ff00807c088268dd859e7c4a5dab",
"assets/use-two-factor-auth-kpel6Zcb.js": "771c519273e76ec8a5bea59c35605f01e5a55b353443c742c8f22d7bd9691504",
"assets/utils-CCDJ05Ll.js": "ef54f43266d404b8ffe4e5487b346060eaf81d819317f523c966aa3e7490deb8",
"assets/value-network-BGoAnXyl.js": "75df28e17011c8b0bb16ba638481e7131b3f8eb342d7369aa2213f6504997a84",
"assets/value-text-BztaYdGl.js": "873576810a6ba4eb8c9c116f53cdc649b21ab2995aa2adadd4c85130b04bacd2",
"assets/verification-BOcn3HIw.js": "10addac3d8f1865e855943e0685e88a268ffd8013ff7a7d51fb89d755b12074e",
"assets/verify-email-DC21S6LB.js": "1f432fc8ae36144b544a06b9bf7748bef9c0f87f5b936e1bfc1a3f2aca7bdc28",
"assets/wayfinder-Dp7PqxvV.js": "3d4c90228fda731e37f541f3087fdf5387d9d59433e35b267b64a97196f70781",
"assets/welcome-SvYVRhja.js": "c08a10c9f69f7b2863d5225dacc36be710fd3977f1d9f92b477a72d3f8e83ed0",
"assets/workspace-4_R1CLYI.js": "5d4c742569d9ad33ac7bac01c6433c646f79f939d2f57b7878860c0d25dcee22",
"assets/workspace-B8XhXQw8.js": "1bb62146e2e205a5e3309258444d663d53b53efee91da2cd0686866547e27be5",
"assets/workspace-Dm3sNpo2.js": "33c27868edb3865c6bba5ede556ed2a2aec8e73f5d70a8815bb94024756118e3",
"assets/zone-BTGy6_nX.js": "03fab72d27dad4bf82ff732665acea79a9b290abd929fbea53c2ba31d2841e3e",
"assets/zone-attachments-C0x5nayn.js": "a65c2a149310ed8bd455d39ac0404261c47b6ddd9bf43df7d3ff2576e77a7c21",
"assets/zone-map-BQAAUcFA.js": "3064db54e3fc441ae97c6ecb660b4ec4e31ade38d47c4c0d75e88cb713471d58",
"assets/zone-relations-BhHp793j.js": "f4552324337f0e0f7e0b73ef43faf2bb2248bf4fc7ad2a2d4deb06e31ccb902f",
"assets/zones-BHSVii1k.js": "c0d2e75f7bd9e7c45ece79ff19b8caf8b1f5b380cd80c975afcf77de487a36a9",
"fonts-manifest.json": "66edf17c93351fe01158be7414a441a762f106417c74351881876b405b8b10ca",
"manifest.json": "2a6b87fc0db4c1ef31664e0fe7cd8d0f2ee1d15cc5947add9d208c6cd7d843d9"
},
"active_protected_hashes": {
"app/Http/Middleware/HandleInertiaRequests.php": "abce9c179b048c2066cb0db888bf932876c18e284a7afc47ef55757959a8aa5b",
"app/Services/OpportunityCanonicalContract.php": "ca68669ad413534d8fa340ebeae6245b802a14568d4d33b050fa17b37dbdeb53",
"app/Services/OpportunityProfileWorkflow.php": "9d2da9fa6d1c4c13b0f4c6827c94d69f4ed36b8d29671912b700942c1ccd33f0",
"app/Services/InvestorPath.php": "40472accc81a1b6098469b1bc7dd4fd7846cb67035415356ddd26c626f24425f",
"app/Http/Controllers/LandAssistanceController.php": "074fa75a5e4e61adb900fcc8be34b3712864bb018d90587054021bd151e8e329",
"resources/js/pages/land-assistance/form.tsx": "62321e145614683b7ce382b226fb34b4dfd1f4be58f9e2b5cfadb3ac990bb84b",
"app/Http/Controllers/ExistingBusinessController.php": "3fba0acccdbf09f8d749a28a0113d0fe36a5f5021a0421c5c1fd2684f92bc167",
"app/Services/CountryCatalogue.php": "625aa4bf2d93cfc471fb547de19a4bd08b9e5e01bf165a18b1076507ff2946d9",
"resources/js/pages/investment/business-interest.tsx": "e93a54ee1beaf583c1b6534a0c5435804bbe03b6f82c4a0f73e91f836996c871",
"app/Services/OpportunityContacts.php": "e6bd6d786cb8b0ecfcb1e4bbe6778e2bf1cf5460650db2fd9f0e443e096e7827",
"app/Services/OpportunityResources.php": "40071ebb691643685e3aacc96bdcc97b3d590ee23716850cebb39609fc282a38",
"app/Services/ExistingBusinessIntake.php": "6719a3e6d3dae6a8813fa0d824cb2714ff90f4ee54869269aefb6b8be59ff911",
"app/Services/InvestmentCatalogue.php": "069a3acb185ce08f011e7e4a3572e8dd17b29f9ac3d79f0090d1d897e06831de",
"app/Http/Controllers/PortalManagementController.php": "a5d551875800794e7c3a58423e27060d9f2a533ffd612d1feb588f0b5d20c731",
"app/Services/OpportunityCategoryFields.php": "eb388758f5b3587efa33b7b9f898471fdd1558c353cb8d7253375d1337cf5c82",
"resources/js/pages/investor-path/show.tsx": "f9c9939304ed5f71567e69e927caabc870add7456eb1c45fe64ffecb8bae4030",
"app/Policies/ExistingBusinessPolicy.php": "2c3d1b6b34a8da4e11a686bc14dc9113d0dade7f2c3d02148446354a674a8f5f",
"resources/js/pages/investment/shared.tsx": "cb46b68b41611a45791681b5e142138a0263334ea859d891b7e76e8ac3085b41",
"resources/js/pages/investment/catalogue.tsx": "00e211056aebabff87fbdc22bc7a7d2b73f9d4b48dd047a4964d5a53fa70da3e",
"app/Models/Opportunity.php": "f19abae14969f0f38c87c06c7f38d62c405634631768498f8ad6948e23706960",
"resources/js/pages/investment/detail.tsx": "ae74fea03b09762c466379a8bafc25c6c9aed7036270e92334a2c952b77299d4",
"resources/js/components/opportunity-canonical-fields.tsx": "421641f8d71477d94604d9ea641112405b4bcb42372b42c44c25eaee506e900f",
"app/Services/InvestmentRelations.php": "40d21e1367b88565de05385b455e7480671eb3dcb98685c9f3239983c14b0280",
"app/Http/Requests/StoreLandAssistanceCaseRequest.php": "6df4208db1b7dbed784dd2d7a623f03123138012b025a855bf075c911b7f1056",
"resources/js/components/portal-grouped-menu.tsx": "4f3e5b469203fe47a7c40aaf3e2ee50f0a0baf682c4f200d02071ea932884a4b",
"resources/js/pages/land-assistance/case.tsx": "faa5ac5281e2aff4a52c34ad849e66d18de6da301c27cd918c41a2ac0faf4855",
"routes/land-assistance.php": "1584558caa988eba05233d5f5f12fb78075382f00bf19a44fdf50bfcf7c9ee25",
"app/Services/OpportunityReviewMateriality.php": "efc0b17a75bb3063bc2995e85d0c571af4692daad1c41e342607beea6d6bc47f",
"resources/js/lib/portal-navigation.ts": "bf7c2056cf6faca5fc71556bf475cbd5c21792a0fd0ef13a8d696c2983c3e67b",
"resources/js/components/opportunity-profile-actions.tsx": "fc15c2e1d07b027ccedb26fd673b67f018cd956f1f025cec8e1b358614cb65d7",
"resources/js/pages/management/opportunity-draft.tsx": "057614b472d66260a2e744e0978f527b05e23fe626ab21e676660c4f38b93d26",
"resources/js/lib/profile-json.ts": "04e5f10a1c8b214df2d335b586e92e761454e8a3f6d905d003ba8b8764f21b18",
"app/Http/Controllers/OpportunityManagementController.php": "571adbb53affd7ec2627ef4a172423913f574bea6162562a19939e07a914b54c",
"resources/js/pages/investment/business-wizard.tsx": "4b59e03fd78faa0b665be3d6819ea79b28091d8d6936560616358daa2ba6b227",
"resources/js/pages/investment/business.tsx": "081da82ea6a68dd48096601dc949f76b9577e605048231baa501068207c36a72",
"public/build/manifest.json": "e21d388f2e71bcd762c476d3e0bd1ae7c608ca57cafc2381c2a8888ce5d4efbf"
},
"activation_authorized": false
}
@@ -0,0 +1,18 @@
{
"at": "2026-10-15T12:49:51.720353+00:00",
"revision": "B-final-fabf722bc8c6",
"ZIP": "C:\\laragon\\www\\portal-investidor\\outputs\\investmoz-audit-current-20261012\\investmoz-opcao-B-candidata-final-revisao-20261015-fabf722bc8c6.zip",
"ZIP_sha256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"bytes": 7771394,
"entries": 265,
"all_manifest_hashes_and_ZIP_entries_verified": true,
"CRC_verified": true,
"known_private_values_absent": true,
"source_count": 35,
"build_count": 173,
"backup_restore_verified": true,
"active_protected_hashes_unchanged": true,
"functional_tests_repeated": false,
"activation_authorized": false,
"active_changes": 0
}
@@ -0,0 +1,47 @@
import pathlib,json,hashlib,zipfile,datetime
r=pathlib.Path.cwd();o=r/'outputs/investmoz-audit-current-20261012';d=o/'B-ativacao-concluida-20261015';d.mkdir(exist_ok=True)
def read(p):return json.loads(p.read_text(encoding='utf-8-sig'))
def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest()
def write(p,v):p.write_text(json.dumps(v,indent=2,ensure_ascii=False)+'\n',encoding='utf-8')
b=read(o/'B-activation-fresh-backup-20261015.json'); private=pathlib.Path(b['private_directory']); switch=read(o/'B-activation-file-switch-20261015.json');before=read(private/'backup-proof-private.json'); staging=private/'candidate-staging'
for n,h in switch['sources'].items():assert sha(r/n)==h,n
assets=list((staging/'public/build').rglob('*'));assets=[p for p in assets if p.is_file()]
for p in assets:assert sha(r/p.relative_to(staging))==sha(p),str(p)
retained=0
for n,h in before['file_hashes'].items():
if n.startswith('public/build/') and n not in ['public/build/manifest.json','public/build/fonts-manifest.json']:assert sha(r/n)==h,n;retained+=1
for n in ['config/inertia.php','config/investor-path.php','composer.lock','package-lock.json','bootstrap/app.php']:
if n not in switch['sources']:assert sha(r/n)==before['file_hashes'][n],n
assert not (r/'storage/framework/down').exists()
for filename,expected in [('investmoz-opcao-B-candidata-final-revisao-20261015-fabf722bc8c6.zip','c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78'),('investmoz-B-suplemento-C137-sequencia-final-20261015.zip','182fb269536aa7bd84b8694ec54d1b39bf5b072abe91d0f4b1284389755fc620')]:
p=o/filename;assert sha(p)==expected
with zipfile.ZipFile(p)as z:assert z.testzip() is None
v={'at':datetime.datetime.now(datetime.timezone.utc).isoformat(),'candidate':'B-final-fabf722bc8c6','C137_included':True,'result':'activated','target_url':'https://portal-investidor.test','sources_verified':len(switch['sources']),'staged_build_files_verified':len(assets),'prior_build_assets_retained_verified':retained,'only_missing_migration_installed':'2026_10_09_190000_prepare_investor_path','authenticated_actor':'Osmane Nala','INVESTOR_PATH_ENABLED':True,'maintenance':False,'existing_business_rows_preserved':read(o/'B-activation-data-preservation-20261015.json')['all_prior_business_rows_preserved'],'COUNTRY02_and_other_env_settings_preserved':True,'DevTools_configuration_preserved':True,'accepted_criteria_repeated':0,'functional_acceptance':'12 closed, preserved','immutable_package_and_supplement_ZIP_integrity_reverified':True,'backup_restore':{'at':b['at'],'tables':295,'sequences':31,'files':815,'dump_sha256':b['dump_sha256'],'files_sha256':b['files_sha256']},'operational_browser_checks':['Authenticated installer: installed, configured, no pending migration','GET /investimentos: Os meus investimentos, empty state and preparation form rendered; no dossier created'],'limitations':['C137: technical evidence, no specific visual acceptance, accepted by Tempo.','Intermediate state without 190000: code inspection/prior evidence, no new HTTP trial, accepted by Tempo.','Line07 correction request nonspecific: documentary limitation accepted by Tempo.','curl local trust check did not establish HTTPS (000); operational opening confirmed in authenticated Edge without bypassing browser security.'],'rollback':'Disable INVESTOR_PATH_ENABLED; restore 36 sources and prior build manifest/config from fresh private backup according to approved procedure. Retain new assets and schema/data; no down/drop or full database restore over subsequent use without reconciliation.'}
write(d/'RESULTADO-ATIVACAO.json',v)
refs=['B-activation-Tempo-authorization-20261015.json','B-activation-fresh-backup-20261015.json','B-activation-file-switch-20261015.json','B-activation-readiness-reconciliation-20261015.json','B-activation-installed-before-flag-20261015.json','B-activation-installed-20261015.json','B-activation-flag-20261015.json','B-activation-data-preservation-20261015.json','B-active-installation-enabled-20261015.png','B-active-path-open-20261015.txt']
import shutil
for n in refs:shutil.copy2(o/n,d/n)
report='''# Disponibilização B concluída — 15/10/2026
A Tempo autorizou a candidata `B-final-fabf722bc8c6` e o suplemento C137. Execução concluída no destino https://portal-investidor.test, com 36 fontes e compilação verificadas.
Backup/restauro fresco: 15:09:24 UTC; 295 tabelas, 31 sequências e 815 ficheiros verificados. A troca ocorreu em manutenção, encerrada antes de abrir o instalador. Apenas `2026_10_09_190000_prepare_investor_path` foi instalada, pela ação autenticada de Osmane Nala, às 15:27:09 UTC. O registo é único (batch 47). A configuração `INVESTOR_PATH_ENABLED=true` foi acrescentada às 15:28:01 UTC após verificação; as restantes linhas do ambiente foram preservadas byte a byte.
A interface confirma instalação e disponibilização configurada. `/investimentos` abre o percurso; nenhum dossier foi criado. A comparação por leitura das 295 tabelas confirma os dados de negócio anteriores preservados. Existem três acréscimos esperados: migration, versão publicada da definição e evento de auditoria. Cache e sessão variaram durante a operação. Nenhum dado QA foi importado.
Os 12 critérios aceites continuam encerrados. Mantêm-se as limitações aceites: linha 07 documental; C137 sem aceitação visual específica; estado intermédio avaliado por código e provas anteriores. Os recibos do instalador reconciliam as provas existentes com a candidata e o backup fresco, sem apresentar essa reconciliação como novo ensaio. COUNTRY02, restantes configurações e DevTools foram preservados.
Reversão: desabilitar o percurso, entrar em manutenção, restaurar as 36 fontes e os manifestos anteriores do backup privado identificado no recibo; sair de manutenção e verificar abertura. Preservar as colunas, definição, eventos e quaisquer novos dados. Não executar `down` nem restauro integral sobre utilização posterior sem reconciliação. O procedimento aprovado e o mapa de reversão continuam anexos na página privada.
A integridade dos dois ZIP autorizados foi novamente verificada localmente (SHA-256 e CRC), bem como fontes e recursos instalados. O recibo acompanha este resultado. O backup com credenciais e base permanece privado no computador; não foi anexado.
'''
(d/'RESULTADO-ATIVACAO.md').write_text(report,encoding='utf-8')
files=[{'path':str(p.relative_to(d)).replace('\\','/'),'sha256':sha(p),'bytes':p.stat().st_size} for p in sorted(d.iterdir()) if p.is_file()]
write(d/'MANIFESTO-EXECUCAO.json',{'files':files})
zp=o/'investmoz-B-ativacao-concluida-20261015.zip'
with zipfile.ZipFile(zp,'w',zipfile.ZIP_DEFLATED)as z:
for p in sorted(d.iterdir()):z.write(p,p.name)
with zipfile.ZipFile(zp)as z:assert z.testzip() is None
receipt={'at':v['at'],'result':'local integrity verified','zip':zp.name,'sha256':sha(zp),'bytes':zp.stat().st_size,'manifest_sha256':sha(d/'MANIFESTO-EXECUCAO.json'),'result_sha256':sha(d/'RESULTADO-ATIVACAO.md'),'candidate_zip_sha256':'c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78','supplement_zip_sha256':'182fb269536aa7bd84b8694ec54d1b39bf5b072abe91d0f4b1284389755fc620','sources':36,'operational_activation_completed':True,'accepted_functional_tests_repeated':0}
write(d/'RECIBO-INTEGRIDADE-ATIVACAO.json',receipt)
print(json.dumps(receipt))
@@ -0,0 +1,176 @@
{
"at": "2026-10-15T13:11:08.745279+00:00",
"candidate_unchanged": true,
"candidate_SHA256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"destination": {
"root": "C:\\laragon\\www\\portal-investidor",
"URL": "https://portal-investidor.test",
"database": "investemoz",
"port": 5432
},
"base_assets_retained": {
"assets/PortalInvestidor-BgL6dTJ9.js": "10801be96219a2706b34dc759532e7a08b203b6ec638c7f6729b1cf4fddf11c4",
"assets/administration-2WaaHIKU.js": "9c03bc25a97aa21be5ef8c85b74315a69c3a6120259b357cdb968c8a6e5d068a",
"assets/ai-DQrxdnH6.js": "3b00bc454ca92da110486068f21b8e21f70aa0932d96268f780b3e488f4d1f9f",
"assets/analysis-CD4pUStB.js": "46b502ceafca3a706703738eb2c9668c122372c044f356a9b4f1917e2a0dd757",
"assets/app-6koffaPt.js": "b533de49ac430eea916345c561b8e2f7976f2587be418e7cdcd731769c8f7629",
"assets/appearance-dMBBCbrF.js": "0c9cf916a6af943147454967c383468a6cec088bb62e1c974759c6cfbd1e2e1a",
"assets/audit-IKTPV-c0.js": "883bb2a2f9b3907fabdbd7bed0dfda89d7195501e973b40b50db8b458d2ce67c",
"assets/bootstrap-confirmation-zU1pT5Kx.js": "ad084cc139f41712f52503bda58577f51bb9a496374d9b97ed521e25d8689fee",
"assets/business-D6sGcu4f.js": "2bc8caebd0720993421209c3ef5897080ca7a0afcd088c3e7887eaec76f945c4",
"assets/business-interest-DMzRJKcE.js": "c974148f8dbc3ad9a4f85de04aef9a6c9a75c709a543cb478c23ec17e05d2b9e",
"assets/business-marketplace-16_YFmUF.js": "7fb9bda513b10c3ec6da6fca4d6b08de856692b06d9fe7956e679dfe359cab4f",
"assets/business-objects-DuARIRpa.js": "9f3e9f60398babed0cfde3c721434d8ff1c44c6700a17bc40fdccc0fb59f1dfa",
"assets/business-opportunity-BNbAOFL9.js": "bca21b309fe374e132930ac0ab6b7be577146a6d0170579667cabbb05c8428f8",
"assets/business-verifications-2Al7Pg8m.js": "0f0411d457fd46239dd9392ed0af3d1a7a9b21a758caa8477860442ce2a69f13",
"assets/business-wizard-B2JTxZMO.js": "625d88feeb23646ddfe87e6fa957d6ea6b86e2d117683cd097738308aaabc382",
"assets/businesses-HEmaf_kQ.js": "f1242130e283258091208a234575d76dc89ebbf1c2ee3ce6a2373b70bd1b0516",
"assets/case-B3iezsz3.js": "a90338784fa5cea8790a99b6e87a3488120ff1cb1756546fc5e3f25756ae10b4",
"assets/catalog-BwNtwLxB.js": "e315e1684e109b23e6b1359f1dfaeac23e3070308ae46ffaeae2883ac0356932",
"assets/catalogue-BxoE4EAL.js": "78e87674a8d5efd96831186c9ffdf00a1ec71f08df956da8b24ff0b745fb4c8b",
"assets/catalogue-DNWlydH2.js": "3be2af1ff8f22aeab9656aa0c9cb20a24fdef2b58122005250c4e0fde3b528aa",
"assets/catalogue-DzIlCfaf.js": "29da3a5ae2a9017493d014bb4c07873776421855e3f55e3e2f379209bfde96f8",
"assets/confirm-password-DoW48TlT.js": "03a03c5b11075a447be7f0121c17e77bebfc71a8d01c82f4e0a525b825f692e7",
"assets/context-BCjd3hOB.js": "ee0bdab947436992c1c330afcce2b6b5de5f63dee5de5cd21b754ef85c3b757c",
"assets/conversation-Lbuxtg60.js": "ce68c556a91313ba9c285531f261687852daddfb45fd7df43e285d05a3d07b79",
"assets/convert-Cmif6Y0u.js": "961a7b53035f1e6aac6713852edd9a10c36051237c0a90c1ca11fa6badd2c274",
"assets/dashboard-B7H-NvB6.js": "0ad70ac7bb9743d5b45187ef4cc4cf401c04550203797e7fb7104d2abdf65aab",
"assets/dashboard-Bv6vwdLI.js": "620ff25df1a8a3d9da67535cfec4ac8d159006f82f5b39c79736dbdf3276bb36",
"assets/desk-internal-operations-BgotJDzO.js": "bacf4ee9b3b0506218b0b6cf222c89e1ee291c8b35402581d5a314952917a8fb",
"assets/detail-lc1sZGLv.js": "1f3b23fb44758259fb5b2ec6e9babcfb055e822f72a194ce22b06ee75162332e",
"assets/detail-xVTgKqyJ.js": "5690761afeae25a598bae253cd2627c7d9980571ec919b1f3806f69d3ec86bbd",
"assets/dialog-BYzV5tSn.js": "cee51bfbd4bc17f7f4b31f1abd4ce4cc7f3a58e35b61072256d07b4b499b35b6",
"assets/document-BwUuCxkg.js": "7e36ac4f4b8fa6b930d66cc6fcd63991ed47930455a3c3a17bac16d16a008cb3",
"assets/editor-2DyDAvVU.js": "27c4ec0bc20ee4d026028baba909b8a8a41a01c77f4913fe72147bb93a11427b",
"assets/editor-4WTAzpYk.js": "1bd51720aecab997486b3777f134c56d3176c3f4147b9e61b49358d1b6e51d08",
"assets/editor-Czh8O56e.js": "9b84ebd832a595121f58ed9dc7c02e07a73202183b3fca5b1ba2ed85f63549cd",
"assets/education-DPfjwmlA.js": "071410349c531db5be48c34976c6f3fd685ac22b57dd61f20bcab4fba36dc7dd",
"assets/fonts-C9MNnjVw.css": "3846a9bb60bfad92960eadcccaf0b4e129d74b11d48791506c8d1a827a385cc8",
"assets/forgot-password-NuXRKj0-.js": "0a0643d310e85a60e40f5d7ff4b7cb822e794c09d33bbb248ad4e945be91a4de",
"assets/form-BmewvnzL.js": "c4d819355c20014d465af231a448d639f4bf8408f46e99865feed4fe25cd90a7",
"assets/history-BD0biKsC.js": "85c91b9bb6083e85c487b9d55a294ec01c24a841adf7f62fb2d9fb185d2a817f",
"assets/install-BOKZXUPn.js": "9cb97a45cbf94ea827ad311cc641206195f5851acc4dc468c691b3df6509e217",
"assets/installation-CZ_bcFXw.js": "6e99ef762bb7fe7856a3587cc48aaf954686d6626b7cc55182189660ff09bc90",
"assets/installation-CuUS64JQ.js": "abd1ab03350e5f8e76aea6769cff69dfe9376ebc732cc00290641b7b4555b5f4",
"assets/interactive-investment-map-kc25PBcM.js": "4957ebb3aec19a0c4bd47816136c5392bf9a3e94cf74b1b787d0bb3ec4dec15f",
"assets/interest-Dx3i-rDY.js": "6d6db408fa412ff92271af65b011be404063800ac2de82f7dc49f94570dccc01",
"assets/interests-DbjR9rUG.js": "b08683b93a3cff1b202015a2a00c51361c2d326d5077f8e8bf4c078c6672b003",
"assets/investment-map-panel-D4UkHert.js": "95f145375e67c314ccfd5303f2aa3561f8862dd3e7da1b53285c0ca240628a62",
"assets/investment-territory-Bj7E9cdW.js": "4fdb10fc48dbcc36eaf21551b2871413c4a47c7a735110a836fc7f5dfd75e0cd",
"assets/investor-B2RRfbRM.js": "a52f9eea82fbaa26c10a6be8c076d564dabafda5bc9c3f9792afb102e18cd026",
"assets/investors-DO2PHXP6.js": "eb7b592ad06c01720b62b313c558ba2d946008fa476913e97e7fd1dc4f1c8c55",
"assets/lead-BiFql0_x.js": "8f0a58049e7d6c6f6606ec187873f361af5945b4cf6a927eb5cdc12d0f946b76",
"assets/leads-DKvcU0F-.js": "2eeb1d56ac5cf1d3c9087905afa33d1eae5db674c284c1c5ca39d84d62400c64",
"assets/login-pFhq8f0A.js": "7e9912ec9ae8d564ecd96fa00274cea053fef9e2b76aa93d7b347006d3a2351e",
"assets/manage-CEXfP-bD.js": "a1d9c138ebc0bafd2bc3a7b38457b57bae3d94bf74c94c87ced5010ccca5e0fa",
"assets/notifications-D7YtOqH-.js": "14a98ee971b32f48a95784c434437b199209492635608f6a3443bb89b87cccd9",
"assets/opportunities-BeP1nUjV.js": "819e9226bce5365a80c00079d7d5663144a28e0178b7444e58b10911a2580d3a",
"assets/opportunity-draft-DY2xk8f5.js": "e071315aedf9237da3aa34f430816214017a838ad01dadcb1d5c259fa2b29826",
"assets/opportunity-install-LOjhly-M.js": "1d9021852aedf2518a77fb11124ac82a98b02b1aa07d4883c064c1193d07e20b",
"assets/opportunity-origin-P65CBahN.js": "9212b0eac1abaeebca3434dd1778a34a5b62061d544db7c87818ed27290053b4",
"assets/opportunity-resources-f8hcGJe0.js": "44af61f09d42c69864d3ab05a071583c44b89c5b7c21809011d160bc91635747",
"assets/panel-DwBN6cRB.js": "5c3374e5afe87859c24d04145586a4622a8462e064b801fe761fd9e14d10091f",
"assets/passkey-verify-CHbNONJw.js": "811cf0e592bad83b6b2c3ee6f33463aefc0fe9da158e70043a79081d0eef16e7",
"assets/password-input-CZEiv6-Y.js": "6cf06107091b98408d1f8e2eb78c483748ca05e4b6527f10f6d415cc9aacf26f",
"assets/portfolio-BeA7vA21.js": "daf733a04f73f156c02f24250f7776fce51e0bde975a0532593602b6bf2cefb3",
"assets/profile-7FEFpszu.js": "6afac1c5e20cb541be51628f561400caa21eee2e6af566142aea97086ba7ab43",
"assets/profile-json-Bb5H6-rZ.js": "0c4720d8d5baabfcc199d66bc171b014152f3cf2ff40b542d38e86cc1e04a77a",
"assets/profile-kiqG9EDh.js": "b4278437074b9f335a2e70f1c991a704a8ad3578053655561e3f9f6dd05ff3e0",
"assets/references-a6GUerWr.js": "dc0ad799c3a4c5a419d70c98f766e7d4d838733ca661e231924dc5e322af5237",
"assets/register-Dz4XuOsS.js": "4df16cae0d61de9928e19467191b6be173da8995a5c9ad1ca3a296d13a82b596",
"assets/relationship-repair-BbPpEIow.js": "e7c9f476e2a65d9802910a945caed97d741202177d5cbb67c0f48a46e84ca85c",
"assets/request-BnuYhHmw.js": "47eb74e227f0d2dc9a41357f2b4a696daafe4b8dd90b076e945074cbc95c7fc4",
"assets/request-DNLOT7Ur.js": "bfc00723597db137c39f10460b1979af05fa431143633defb9e318763dc77fa8",
"assets/reset-password-FH2pmEDN.js": "fb9e46c168c4e02ae28831fe6b49b51fbd4b1261e8b922f51720444e224a0064",
"assets/result-BaPIoTbf.js": "e55b520c37e0c6d2ffa0f117d434018675f7272e257d252f2fde3c359ec4aea8",
"assets/room-DtK7QZt7.js": "56fa46e93d482c382bb1f5018e52fa7af9e3543a5d565586c04f5eff6f38ab71",
"assets/security-B_oLYs5-.js": "e0f7a12c7869894ba6c2af31a1f8c4ae3b62bbeb825e2d7d6458ec4cbda58627",
"assets/services-BZQcAJGT.js": "1960b184275a312174a31eb30ed3931ee04d25bfa8726b1602caee61a3664f1f",
"assets/shared-BEDl7WFV.js": "75a67b27609c6df591628e9c385b219b2ca7fd8c09358a0eba2fed662bdb6bed",
"assets/shared-CJucoqgO.js": "ee33544fb6f711d44818c5662a3cd186c9761fd7c6614f8eaaee10eb14be3ffb",
"assets/shared-CNf7SPwM.js": "a25ddb63a1ddc8c2f84ca1ba006e55de29d88f6711e4b8fcd1ca6ed9135cb343",
"assets/shared-CXW4I9EU.js": "e69a99b96195fce0f3f96bca7cd1636b6ac860bda13c2917599e8636cd022fc1",
"assets/show-B3_nUTlb.js": "bfaf81cd443ddf447999ef6715ae53bccf3bee44b9052169782a744b40f499a8",
"assets/sources-DqLhX3mx.js": "1066ed12003204175aeb81a08c1ef74d36aaa4b6c58df3313565a27e8051e4b8",
"assets/structure-geography-D0mJ03tA.js": "816a83663ec718609353a0e8d376983e8b751339fa30a67d6e77312af66dd845",
"assets/structures-Bw3yjEkY.js": "4ad7e1a8956deb2d75a245a556de83ef9ff0116226880b9a1530707684eb1ca7",
"assets/submission-BztVPQOB.js": "bbfcb673921e5653c24d0a923d80de5be070d7e8feddcc2505e582e0cfd543db",
"assets/territory-associations-BghnoFKh.js": "1c5a852fe02917a109a6b046409d0a07fd7e4ab15ca7e7cb5543a2c1f0ca774c",
"assets/territory-geometry-import-BgUiqJjl.js": "a2dff089e300e59db3692a582575bf77da407646c04720701c3eeabf88a1acb7",
"assets/territory-geometry-preview-DqO4V0-r.js": "7af32d2f6347d59e5c93779caa86153853f352dcce89f2b4dc2bd6a47713f024",
"assets/two-factor-challenge-C-j2ixF_.js": "eac048f285e5dfd3daab2fe4ba6891087a8068547aa2dd1f0865e761938b0efb",
"assets/value-network-Bw5_SMDf.js": "cb1648f4d2839bb93211426c8ce9eac9e5414648d6728ffbbf0e94bcd7e47afa",
"assets/verify-email-DGF0VDk6.js": "2bfe6141b58c741a570d9f5f9e0af73a7f045509203fe8d360e550b7613109a7",
"assets/welcome-CPCJPF06.js": "d622fed9d44676a1243143766cd2849cff89354dc4ab610a74921feadd357807",
"assets/workspace-Bo7B3eQ-.js": "2663a517177c1caafd6ce35ea5fbcbed97c3a0a01bcb8785b1576a8604a7b4f5",
"assets/workspace-CtTfcNTT.js": "a780023d248ea787dfacba88b97f40124c8e00c43ba98d3c358eea48a79ed227",
"assets/zone-H5olHugq.js": "d68e37fd62695b903544352c77817bcab468710f2e073c3c4c0ed54db5ec594c",
"assets/zone-attachments-CANe4XzA.js": "af0f90d0f9ca0c5f382e3a459e42c2d2d2213bbcd1517e2234da684acd1f34c7",
"assets/zone-map-DKg4YJ5O.js": "b4de181ae51a74c1f0b36d9c93f98adfd0a45074fad2259923184508597d41e2",
"assets/zone-relations-D-lZGYpC.js": "b189b5ed4a6787a457c804350234d25523d691e3f6b4f1219fc61323874cf5bc",
"assets/zones-PkKrJeXJ.js": "4d1280a4de3116ca6650a8f506a1e6489dc7bfe73251092dda4adb0bba9bb4c4"
},
"fonts_dependency_already_in_base_ZIP": true,
"dependency_lockfiles_equal": {
"composer.lock": true,
"package-lock.json": true,
"vendor/composer/installed.json": true
},
"flags_read_only": {
"INVESTOR_PATH_ENABLED": "absent; use configuration default",
"VIRTUAL_DESK_ENABLED": "absent; use configuration default",
"PORTAL_ORGANIZATION_COUNTRY_ENABLED": "true",
"PORTAL_PROFILE_ENABLED": "absent; use configuration default",
"PORTAL_PROFILES_ENABLED": "absent; use configuration default",
"PORTAL_OPPORTUNITY_WORKFLOW_ENABLED": "absent; use configuration default"
},
"migration_dependency": {
"file": "database/migrations/2026_10_09_190000_prepare_investor_path.php",
"sha256": "939c2b2e5f9fd6a454fe7f8dd4f4373fd7df53f80e5c5f169db08e6e4c676728",
"columns_missing": {
"investor_journeys.path_definition_id": {
"table_schema": "public",
"table_name": "investor_journeys",
"column_name": "path_definition_id",
"ordinal_position": 18,
"data_type": "uuid",
"udt_name": "uuid",
"is_nullable": "YES",
"column_default": null
},
"journey_steps.path_detail": {
"table_schema": "public",
"table_name": "journey_steps",
"column_name": "path_detail",
"ordinal_position": 14,
"data_type": "text",
"udt_name": "text",
"is_nullable": "YES",
"column_default": null
}
},
"installed_in_restored_QA": true,
"installed_in_destination": false,
"existing_authenticated_installer": "GET/POST https://portal-investidor.test/management/balcao-install",
"no_generic_migrate_or_SQL_bypass": true
},
"inherited_scope_discrepancy": {
"id": "C137",
"source": "resources/js/pages/partnerships/room.tsx",
"destination_sha256": "43b64ce253bf450888fcd3b10d5e5860cc2633aed29a82cde965d82ae99172e3",
"QA_source_sha256": "fea8a156ee7ff8b24492ec0bfe5e61ab4d6ecefe588f65bec67909fc704df53a",
"present_in_original_base_compiled_bundle": true,
"present_in_current_candidate_compiled_bundle": true,
"included_in_35_source_delta": false,
"behavior": "UI permite ao autor retirar partilha existente após encerrar sala; bloqueia novas partilhas.",
"approved_B_scope": "salas/C137 fora do loteB; não inferir aceitação ou autorização de ativação",
"new_code_written_in_this_task": false,
"resolution": "Manter candidata imutável; exigir decisão expressa da Tempo antes de ativar bundle com esta diferença. Não substituir silenciosamente por outra compilação."
},
"operational_activation_ready": false,
"reasons": [
"Migração190000 existente ausente do destino; instalação autenticada e flag são ações separadas ainda não autorizadas.",
"C137 herdado do bundle base está fora do âmbitoB e fora do delta35; requer delimitação expressa antes de ativar."
],
"active_changes": 0
}
@@ -0,0 +1,26 @@
{
"at": "2026-10-15T13:11:11.820680+00:00",
"ZIP": "C:\\laragon\\www\\portal-investidor\\outputs\\investmoz-audit-current-20261012\\investmoz-opcao-B-revisao-completa-operacional-20261015.zip",
"SHA256": "2f68f0410bed011c0aab14700a7c6fee9b460540e8ad0dbf9d30b1c4b7691f46",
"bytes": 7815403,
"entries": 15,
"recursive_entries_checked": 703,
"CRC_and_all_file_hashes_verified": true,
"candidate_original_bytes_and_SHA256_unchanged": true,
"candidate_SHA256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"candidate_manifest_and_SHA256SUMS_verified": true,
"base_ZIP_verified": true,
"Vite_imports_assets_fonts_verified": true,
"boot_on_restored_clone_passed": true,
"destination_35_sources_769_assets_configuration_hashes_unchanged": true,
"known_local_credentials_absent": true,
"functional_acceptance_preserved": true,
"12_criteria_repeated": false,
"activation_ready": false,
"activation_gaps": [
"190000 ausente no destino",
"C137 herdado fora do âmbitoB no bundle"
],
"activation_authorized": false,
"active_changes": 0
}
@@ -0,0 +1,120 @@
{
"at": "2026-10-15T13:08:40+00:00",
"clone": "b_final_restore_20261015_124723_test",
"port": 55441,
"destination_schema_equal_to_clone": false,
"destination_migrations_equal_to_clone": false,
"destination_column_count": 1970,
"clone_column_count": 1972,
"clone_only_columns": {
"investor_journeys.path_definition_id": {
"table_schema": "public",
"table_name": "investor_journeys",
"column_name": "path_definition_id",
"ordinal_position": 18,
"data_type": "uuid",
"udt_name": "uuid",
"is_nullable": "YES",
"column_default": null
},
"journey_steps.path_detail": {
"table_schema": "public",
"table_name": "journey_steps",
"column_name": "path_detail",
"ordinal_position": 14,
"data_type": "text",
"udt_name": "text",
"is_nullable": "YES",
"column_default": null
}
},
"destination_only_columns": [],
"changed_columns": [],
"clone_migration_names": [
"0001_01_01_000000_create_users_table",
"0001_01_01_000001_create_cache_table",
"0001_01_01_000002_create_jobs_table",
"2024_01_01_000000_create_passkeys_table",
"2025_08_14_170933_add_two_factor_columns_to_users_table",
"2026_01_01_000001_create_sectors_table",
"2026_01_01_000002_create_opportunities_table",
"2026_01_01_000003_create_interest_requests_table",
"2026_09_24_000100_investmoz_extensions_functions",
"2026_09_24_001000_investmoz_identity",
"2026_09_24_002000_investmoz_content",
"2026_09_24_003000_investmoz_geography",
"2026_09_24_004000_investmoz_projects",
"2026_09_24_005000_investmoz_clusters",
"2026_09_24_006000_investmoz_corridors",
"2026_09_24_007000_investmoz_crm",
"2026_09_24_008000_investmoz_journey_aftercare",
"2026_09_24_009000_investmoz_education",
"2026_09_24_009500_investmoz_document_links",
"2026_09_24_010000_investmoz_governance_ai",
"2026_09_24_011000_investmoz_integrations",
"2026_09_24_012000_investmoz_indexes",
"2026_09_24_013000_investmoz_triggers",
"2026_09_25_100000_extend_crm_intake",
"2026_09_25_110000_create_investment_gaps",
"2026_09_25_120000_add_interest_submission_receipts",
"2026_09_25_130000_investment_portfolio_journeys",
"2026_09_26_100000_education_intake",
"2026_09_26_110000_education_investment_proposals",
"2026_09_26_120000_investmoz_ai_foundation",
"2026_09_26_140000_portfolio_owner_approval",
"2026_09_27_120000_public_portal_services",
"2026_09_27_140000_investment_unification",
"2026_09_27_150000_investor_workspace",
"2026_09_28_090000_version_investment_dossiers",
"2026_09_28_100000_investment_zone_foundation",
"2026_09_28_110000_zone_geometry_review",
"2026_09_28_120000_investment_submission_zones",
"2026_09_28_130000_existing_business_foundation",
"2026_09_28_140000_existing_business_intake",
"2026_09_28_150000_territorial_registry",
"2026_09_28_160000_investment_primary_territory",
"2026_09_29_100000_territory_integrity",
"2026_09_29_200000_existing_business_form_sector",
"2026_09_30_100100_skills_education_1",
"2026_09_30_100200_skills_education_2",
"2026_09_30_100300_skills_education_3",
"2026_09_30_100400_skills_education_4",
"2026_09_30_100500_skills_education_5",
"2026_09_30_100600_skills_education_6",
"2026_09_30_110000_project_dependency_integrity",
"2026_09_30_120000_extend_existing_business_marketplace",
"2026_10_01_000100_create_reference_catalogs",
"2026_10_01_000200_create_simulation_execution_core",
"2026_10_01_120000_create_simulation_form_drafts",
"2026_10_02_120000_allow_owner_to_read_soft_deleted_simulation_drafts",
"2026_10_02_160000_extend_existing_business_opportunity_types",
"2026_10_03_170000_create_simulation_tax_rule_governance",
"2026_10_03_180000_govern_investment_structure_relations",
"2026_10_03_190000_allow_public_read_of_published_tax_parameters",
"2026_10_03_200000_create_land_assistance_cases",
"2026_10_03_210000_make_interest_request_email_nullable",
"2026_10_04_120000_add_opportunity_geography_scope",
"2026_10_04_120000_add_simulation_draft_continuity",
"2026_10_04_130000_extend_investment_zone_records",
"2026_10_04_140000_create_investment_zone_attachments",
"2026_10_04_150000_relax_zone_operator_publication_requirement",
"2026_10_04_160000_extend_zone_development_and_area_scopes",
"2026_10_05_120000_extend_portal_document_catalogue",
"2026_10_05_130000_add_document_malware_scanning",
"2026_10_06_140000_allow_unapproved_private_portal_resources",
"2026_10_06_180000_add_document_applicability_dates",
"2026_10_06_200000_add_document_requirement_evidence_links",
"2026_10_06_210000_allow_informational_zone_publication_without_second_publisher",
"2026_10_06_220000_add_company_purchase_business_modality",
"2026_10_07_160000_extend_internal_partnership_exchange",
"2026_10_07_190000_create_internal_virtual_desk",
"2026_10_08_120000_extend_desk_investor_guidance",
"2026_10_09_020000_extend_opportunity_management",
"2026_10_09_030000_extend_opportunity_resources",
"2026_10_09_190000_prepare_investor_path",
"2026_10_10_040000_create_portal_profile_authorization",
"2026_10_10_050000_extend_organization_country"
],
"new_migrations_in_candidate": 0,
"active_changes": 0
}
@@ -0,0 +1,14 @@
<?php
ini_set('zend.exception_ignore_args','1');$root=dirname(__DIR__,2);require $root.'/vendor/autoload.php';
$proof=json_decode(file_get_contents(__DIR__.'/B-final-backup-restoration-20261015.json'),true,512,JSON_THROW_ON_ERROR);
$e=Dotenv\Dotenv::parse(file_get_contents($proof['private_recovery_directory'].'/application-boot/.env'));
if($e['DB_DATABASE']!==$proof['restore']['database']||(int)$e['DB_PORT']!==55441)throw new RuntimeException('Clone only');
$pdo=new PDO('pgsql:host=127.0.0.1;port=55441;dbname='.$e['DB_DATABASE'],$e['DB_USERNAME'],$e['DB_PASSWORD']??'',[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION]);$pdo->exec('BEGIN READ ONLY');
try{
$schema=$pdo->query("SELECT table_schema,table_name,column_name,ordinal_position,data_type,udt_name,is_nullable,column_default FROM information_schema.columns WHERE table_schema='public' ORDER BY table_name,ordinal_position")->fetchAll(PDO::FETCH_ASSOC);
$m=$pdo->query('SELECT migration,batch FROM migrations ORDER BY migration')->fetchAll(PDO::FETCH_ASSOC);
$d=json_decode(file_get_contents(__DIR__.'/B-destination-preflight-readonly-20261015.json'),true,512,JSON_THROW_ON_ERROR);
$a=[];$b=[];foreach($d['schema_columns']as$x)$a[$x['table_name'].'.'.$x['column_name']]=$x;foreach($schema as$x)$b[$x['table_name'].'.'.$x['column_name']]=$x;
$p=['at'=>gmdate('c'),'clone'=>$e['DB_DATABASE'],'port'=>55441,'destination_schema_equal_to_clone'=>$schema===$d['schema_columns'],'destination_migrations_equal_to_clone'=>hash('sha256',json_encode($m,JSON_THROW_ON_ERROR))===$d['migrations_sha256'],'destination_column_count'=>count($d['schema_columns']),'clone_column_count'=>count($schema),'clone_only_columns'=>array_diff_key($b,$a),'destination_only_columns'=>array_diff_key($a,$b),'changed_columns'=>array_keys(array_filter($b,fn($x,$k)=>isset($a[$k])&&$a[$k]!==$x,ARRAY_FILTER_USE_BOTH)),'clone_migration_names'=>array_column($m,'migration'),'new_migrations_in_candidate'=>0,'active_changes'=>0];
file_put_contents(__DIR__.'/B-operational-schema-readonly-20261015.json',json_encode($p,JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));echo json_encode($p);
}finally{$pdo->exec('ROLLBACK');}
@@ -0,0 +1,3 @@
# Preparação operacional — suplemento da candidata mantida
Abrir PROCEDIMENTO-EXATO.md e PROPOSTA-UNICA-TEMPO.md. A candidata final original está incluída em candidata/ sem alteração de bytes. Arranque sobre o clone restaurado verificado; comparação do destino exclusivamente por leitura. Há dois pontos de decisão antes de ativar:190000 ausente eC137 herdado fora do âmbitoB. Nenhum dos12 critérios foi repetido. Este pacote não é instalador nem autorização de ativação.
@@ -0,0 +1,24 @@
# Disponibilização/reversão — procedimento exato preparado, não executado
Candidata imutável **B-final-fabf722bc8c6**; ZIP SHA256 `c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78`. Destino lido: `C:/laragon/www/portal-investidor`, `https://portal-investidor.test`, `investemoz:5432`, snapshot 2026-10-15T13:07:07+00:00. PHP Apache8.5.11/Apache2.4.54; configuração sem cache e DevToolsOFF. Dependências Composer/NPM/installed.json iguais às do ensaio. Matriz exata de35 fontes e173 recursos: `B-exact-deployment-map-20261015.json`; inventário atual769 recursos: preflight. Nada abaixo foi executado no destino.
## Portas de entrada obrigatórias
1. **Não ativar enquanto as duas diferenças documentadas não forem decididas pela Tempo.** Falta a migração existente190000; C137 está herdado no bundle mas fora do âmbitoB. Não declarar estes pontos como falhas dos12 critérios aceites. Não trocar/recompilar candidata para os ocultar.
2. Depois de autorização específica e janela, executar verificação local dos hashes do ZIP, manifesto,35 fontes anteriores,769 recursos atuais, `.env`, config/inertia.php e locks. Se o destino tiver divergido do preflight, parar antes de qualquer troca e atualizar o mapa somente por leitura. Conferir mais uma vez identidade SQL investemoz:5432; nunca usar contas/grants/documentos QA no ativo.
3. Renovar backup consistente **do destino atual**, originais/cifras/configuração/ACLs e metadados, para diretório privado fora do webroot; restaurar em novo clone55441*_test e verificar. O backup QA já verificado não substitui este backup do destino; o backup de código atual preparado é `C:\Users\macbook\.config\investmoz\B-final-recovery-20261015_124723\destination-before-activation`. Não usar o dumpQA como rollback do ativo. Só iniciar a janela após recibo do backup/restauro fresco do destino.
## Sequência futura após autorização
4. Na raiz do destino, com `C:/laragon/bin/php/php-8.5.11-Win32-vs17-x64/php.exe`, usar `artisan down --retry=60` durante a troca; não criar endpoint de reset/segredo de bypass. Não tocar em workers/filas/ClamD/CA por este lote. Preservar flags eDevToolsOFF. Não executar `composer install`, `npm build`, `migrate`, `migrate:fresh` ou instaladores030000/040000/050000.
5. Se autorizada a dependência190000, preparar primeiro as provas frescas do código final/destino nos controlos existentes e usar utilizador real já autorizado manage-portal com MFA em `GET /management/balcao-install`; conferir preview/hash e pendência **somente2026_10_09_190000_prepare_investor_path**. A aplicação idempotente ocorre pelo `POST` do próprio formulário, com CSRF e hash exibido, nunca por SQL direto/configuração de bypass. O serviço conserva as migrações anteriores e adiciona apenas investor_journeys.path_definition_id, journey_steps.path_detail e definição publicada imutável; não converte dossiers. Se backupVerified/qaVerified/pathQaVerified/compatibilityVerified/databaseReady não passarem para o código/destino final, parar; não fabricar readiness nem repetir os12 ensaios para contornar o gate. Instalação não habilita navegação: `INVESTOR_PATH_ENABLED` requer autorização específica separada na mesma decisão de ativação, caso a entrega integrada seja escolhida.
6. Extrair o ZIP para staging privado. Montar a compilação base de `historico/investmoz-B-base-396c691930bc.zip` e sobrepor `compilacao-QA` da candidata; manter fontesCSS/fontes e recursos anteriores. Copiar apenas os35 caminhos de fonte do mapa, verificando before/after e preservando ACLs do destino. Para recurso de nome com hash já existente, só reutilizar bytes iguais; colisão divergente interrompe a operação. **Não eliminar os769 recursos atuais.** Selecionar `public/build/manifest.json` por troca de ficheiro no mesmo volume apenas depois de fontes/recursos íntegros; copiar fonts-manifest correspondente e conservar os ativos da base que referencia. Não extrair o ZIP histórico por cima de código/configuração do destino.
7. `artisan view:clear` apenas para views compiladas, `artisan up` no fim. Não executar optimize:clear, cache:clear ou limpar sessões/filas de aplicação por conveniência. Apache configurado carrega PHP8.5.11 por mod_php; não confundir PHPCLI com PHPweb. Se necessário invalidar OPcache, usar mecanismo administrativo existente/reload gracioso do **Apache ativo** `C:/laragon/bin/apache/httpd-2.4.54-win64-VS16/bin/httpd.exe -k graceful -d C:/laragon/bin/apache/httpd-2.4.54-win64-VS16 -f C:/laragon/bin/apache/httpd-2.4.54-win64-VS16/conf/httpd.conf`, somente com autorização da janela e após teste de configuração; não reiniciar instânciasQA nem editar php.ini. Não foi afirmada necessidade de reload nesta preparação.
8. Conferência operacional pós-troca limitada a hashes, PHPweb/HTTPS, `/up`, `/login`, carregamento do bundle/fontes e logs de arranque; login/MFA normal sem reenviar códigos, se necessário à observação operacional. Não refazer os12 critérios nem alterar registos aceites. Registar recibo final do destino, janela e autor. Qualquer erro500, ativo404, hash divergente, exposição de diagnóstico ou dependência não resolvida exige contenção/reversão, não prosseguimento automático.
## Reversão futura
9. Se houver regressão, manter/entrar manutenção; não executar down de migrações usadas. Repor apenas as35 fontes originais presentes no diretório privado indicado e manifesto/font-manifest anteriores, pelos hashes before do mapa. Caminho originalmente ausente só pode ser retirado se ainda tiver exatamente o hash da candidata, sem apagar alterações posteriores. Recursos adicionados podem permanecer inertes; não apagar arquivos por varrimento. Repor views compiladas por view:clear, verificar HTTPS/arranque, sair da manutenção.
10. Se190000 tiver sido instalado e já tiver histórico, preservar duas colunas, definição e dados; desabilitar apenas a flag cuja mudança foi autorizada e registada na janela. Não repor `.env` antigo inteiro se outras alterações tiverem ocorrido; manter COUNTRY02, workflow/perfis eDevToolsOFF. Reversão de código não recupera a autorização PromotorQA22 nem afeta publicaçãoQA v12. Restauração integral do destino só por decisão adicional, backup próprio verificado e reconciliação dos dados posteriores. Nunca importar o cloneQA.
Esta preparação não executou manutenção, instalação, alteração de flag, cópia para o destino, limpeza, reload ou restauro ativo. Os comandos são roteiro futuro sujeito aos gates acima.
@@ -0,0 +1,9 @@
# Proposta única à Tempo — ativação condicionada, não executada
Manter a candidata B-final-fabf722bc8c6 e a aceitação funcional dos12 critérios, incluindo a ressalva documental da linha07. Autorizar uma única janela de disponibilização da opçãoB **somente depois de delimitar expressamente**, na mesma decisão, a dependência190000 já prevista para o percurso integrado e o tratamento da diferençaC137 herdada do bundle base.
A entrega mantém o mesmo ZIP/hash. C137 permite retirar partilha existente após encerrar sala; não estava no âmbitoB nem nos35 fontes, embora já esteja compilado na base. Não se presume a sua aceitação, não se introduziu código novo e não se alterou a candidata para a remover. Até a Tempo decidir esse alcance, a recomendação é **não ativar**. Se a decisão exigir retirarC137, será necessário autorizar um empacotamento técnico específico; este documento não o executa nem substitui silenciosamente a candidata.
Depois da decisão de âmbito, a mesma janela deve incluir backup/restauro fresco do destino, instalação autenticada190000 se autorizada (flag de navegação como ação separada), troca controlada segundo mapa/hash, conferência apenas operacional e reversão de código se necessária. Não renovar testes funcionais aceites, criar funcionalidades, instalar novamente perfis ou transportar dadosQA.
O arranque no clone restaurado passou. O pacote está íntegro; a ativação ainda não está liberada por causa destes dois pontos de âmbito/dependência. Não é reabertura da auditoria funcional nem autorização para alterar o ativo.
@@ -0,0 +1,14 @@
cba79fbf260da16cdc98209f1ec41f8aa95d8f7eab658cddf48a53a5621e8c14 LEIA-ME.md
dae9afca948cafb8f62234dbf97a222c3d527a742e27de377880d6c7b7220cd6 PROCEDIMENTO-EXATO.md
4ceae8c000117d67fe9f4a884bf3c8cd442e3ad793840f381d946d729801ae05 PROPOSTA-UNICA-TEMPO.md
c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78 candidata/investmoz-opcao-B-candidata-final-revisao-20261015-fabf722bc8c6.zip
dd165edc382a0d221d5dd112022626aa5f573306ece9b9b81a7a9ee7dc2037fd evidencias/B-boot-base-assets-20261015.json
7674a0084f8c18a6ef18d21a89ca6d539523c5d7ab0c09e15a5511e6dd3524f2 evidencias/B-destination-preflight-readonly-20261015.json
1c1c0bf81cf5087561aea711855f66fd65a5e747425d61dc8d7e69f751fd9ebd evidencias/B-exact-deployment-map-20261015.json
8ea27dcd498fe887f6a615941ddb64072738b1c3c682a84839deffbc49865b3f evidencias/B-final-backup-restoration-20261015.json
8c8200f2fb64c5d291205aa451cd82db0dd3ad43c2484f78d94e997d96ae7d0d evidencias/B-final-package-verified-20261015.json
0a43f010902c6c78c2bdaa680db6d4b4749f2b60ddbc21d3180c83b6585269a9 evidencias/B-operational-dependencies-20261015.json
6a54399850c25280feda047c341bd33f1226f14389e5020ea94b5eb891c57c55 evidencias/B-operational-schema-readonly-20261015.json
7744a5e941bef358e9b027fae036a8f2bd708d2e34c017add73d119291119ca9 evidencias/B-restored-clone-boot-20261015.json
939c2b2e5f9fd6a454fe7f8dd4f4373fd7df53f80e5c5f169db08e6e4c676728 evidencias/migracao-existente-190000-referencia.php
712d3244a9f8840fe9d164afcf90cc810275aa6e434f49407b202b4df3935124 manifesto-operacional.json
@@ -0,0 +1,105 @@
{
"base_assets_added_without_overwriting_candidate": [
"assets/PortalInvestidor-BgL6dTJ9.js",
"assets/administration-2WaaHIKU.js",
"assets/ai-DQrxdnH6.js",
"assets/analysis-CD4pUStB.js",
"assets/app-6koffaPt.js",
"assets/appearance-dMBBCbrF.js",
"assets/audit-IKTPV-c0.js",
"assets/bootstrap-confirmation-zU1pT5Kx.js",
"assets/business-D6sGcu4f.js",
"assets/business-interest-DMzRJKcE.js",
"assets/business-marketplace-16_YFmUF.js",
"assets/business-objects-DuARIRpa.js",
"assets/business-opportunity-BNbAOFL9.js",
"assets/business-verifications-2Al7Pg8m.js",
"assets/business-wizard-B2JTxZMO.js",
"assets/businesses-HEmaf_kQ.js",
"assets/case-B3iezsz3.js",
"assets/catalog-BwNtwLxB.js",
"assets/catalogue-BxoE4EAL.js",
"assets/catalogue-DNWlydH2.js",
"assets/catalogue-DzIlCfaf.js",
"assets/confirm-password-DoW48TlT.js",
"assets/context-BCjd3hOB.js",
"assets/conversation-Lbuxtg60.js",
"assets/convert-Cmif6Y0u.js",
"assets/dashboard-B7H-NvB6.js",
"assets/dashboard-Bv6vwdLI.js",
"assets/desk-internal-operations-BgotJDzO.js",
"assets/detail-lc1sZGLv.js",
"assets/detail-xVTgKqyJ.js",
"assets/dialog-BYzV5tSn.js",
"assets/document-BwUuCxkg.js",
"assets/editor-2DyDAvVU.js",
"assets/editor-4WTAzpYk.js",
"assets/editor-Czh8O56e.js",
"assets/education-DPfjwmlA.js",
"assets/fonts-C9MNnjVw.css",
"assets/forgot-password-NuXRKj0-.js",
"assets/form-BmewvnzL.js",
"assets/history-BD0biKsC.js",
"assets/install-BOKZXUPn.js",
"assets/installation-CZ_bcFXw.js",
"assets/installation-CuUS64JQ.js",
"assets/interactive-investment-map-kc25PBcM.js",
"assets/interest-Dx3i-rDY.js",
"assets/interests-DbjR9rUG.js",
"assets/investment-map-panel-D4UkHert.js",
"assets/investment-territory-Bj7E9cdW.js",
"assets/investor-B2RRfbRM.js",
"assets/investors-DO2PHXP6.js",
"assets/lead-BiFql0_x.js",
"assets/leads-DKvcU0F-.js",
"assets/login-pFhq8f0A.js",
"assets/manage-CEXfP-bD.js",
"assets/notifications-D7YtOqH-.js",
"assets/opportunities-BeP1nUjV.js",
"assets/opportunity-draft-DY2xk8f5.js",
"assets/opportunity-install-LOjhly-M.js",
"assets/opportunity-origin-P65CBahN.js",
"assets/opportunity-resources-f8hcGJe0.js",
"assets/panel-DwBN6cRB.js",
"assets/passkey-verify-CHbNONJw.js",
"assets/password-input-CZEiv6-Y.js",
"assets/portfolio-BeA7vA21.js",
"assets/profile-7FEFpszu.js",
"assets/profile-json-Bb5H6-rZ.js",
"assets/profile-kiqG9EDh.js",
"assets/references-a6GUerWr.js",
"assets/register-Dz4XuOsS.js",
"assets/relationship-repair-BbPpEIow.js",
"assets/request-BnuYhHmw.js",
"assets/request-DNLOT7Ur.js",
"assets/reset-password-FH2pmEDN.js",
"assets/result-BaPIoTbf.js",
"assets/room-DtK7QZt7.js",
"assets/security-B_oLYs5-.js",
"assets/services-BZQcAJGT.js",
"assets/shared-BEDl7WFV.js",
"assets/shared-CJucoqgO.js",
"assets/shared-CNf7SPwM.js",
"assets/shared-CXW4I9EU.js",
"assets/show-B3_nUTlb.js",
"assets/sources-DqLhX3mx.js",
"assets/structure-geography-D0mJ03tA.js",
"assets/structures-Bw3yjEkY.js",
"assets/submission-BztVPQOB.js",
"assets/territory-associations-BghnoFKh.js",
"assets/territory-geometry-import-BgUiqJjl.js",
"assets/territory-geometry-preview-DqO4V0-r.js",
"assets/two-factor-challenge-C-j2ixF_.js",
"assets/value-network-Bw5_SMDf.js",
"assets/verify-email-DGF0VDk6.js",
"assets/welcome-CPCJPF06.js",
"assets/workspace-Bo7B3eQ-.js",
"assets/workspace-CtTfcNTT.js",
"assets/zone-H5olHugq.js",
"assets/zone-attachments-CANe4XzA.js",
"assets/zone-map-DKg4YJ5O.js",
"assets/zone-relations-D-lZGYpC.js",
"assets/zones-PkKrJeXJ.js"
],
"candidate_unchanged": true
}
@@ -0,0 +1,28 @@
{
"at": "2026-10-15T12:47:52+00:00",
"source": {
"database": "stability_consumers_20261011_084534_test",
"port": 55441
},
"restore": {
"database": "b_final_restore_20261015_124723_test",
"port": 55441
},
"database_restore_verified": true,
"all_table_rows_hashes_equal": true,
"table_count": 295,
"sequence_count": 31,
"sequences_equal": true,
"candidate_source_and_build_files_restored": 208,
"file_restore_hashes_equal": true,
"existing_document_files_copied_and_restored": 133,
"preexisting_unavailable_document_count": 0,
"private_dump_sha256": "43e02a2ec28cb4eb615b1b6ff7c97590378b3dd5b8585ce00bcdcf00e89a9e13",
"private_recovery_directory": "C:\/Users\/macbook\/.config\/investmoz\/B-final-recovery-20261015_124723",
"dump_credentials_runtime_config_not_in_review_ZIP": true,
"application_boot_in_restored_database_executed": false,
"functional_tests_repeated": false,
"QA_source_writes": 0,
"active_changes": 0,
"activation_authorized": false
}
@@ -0,0 +1,18 @@
{
"at": "2026-10-15T12:49:51.720353+00:00",
"revision": "B-final-fabf722bc8c6",
"ZIP": "C:\\laragon\\www\\portal-investidor\\outputs\\investmoz-audit-current-20261012\\investmoz-opcao-B-candidata-final-revisao-20261015-fabf722bc8c6.zip",
"ZIP_sha256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"bytes": 7771394,
"entries": 265,
"all_manifest_hashes_and_ZIP_entries_verified": true,
"CRC_verified": true,
"known_private_values_absent": true,
"source_count": 35,
"build_count": 173,
"backup_restore_verified": true,
"active_protected_hashes_unchanged": true,
"functional_tests_repeated": false,
"activation_authorized": false,
"active_changes": 0
}
@@ -0,0 +1,176 @@
{
"at": "2026-10-15T13:11:08.745279+00:00",
"candidate_unchanged": true,
"candidate_SHA256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"destination": {
"root": "C:\\laragon\\www\\portal-investidor",
"URL": "https://portal-investidor.test",
"database": "investemoz",
"port": 5432
},
"base_assets_retained": {
"assets/PortalInvestidor-BgL6dTJ9.js": "10801be96219a2706b34dc759532e7a08b203b6ec638c7f6729b1cf4fddf11c4",
"assets/administration-2WaaHIKU.js": "9c03bc25a97aa21be5ef8c85b74315a69c3a6120259b357cdb968c8a6e5d068a",
"assets/ai-DQrxdnH6.js": "3b00bc454ca92da110486068f21b8e21f70aa0932d96268f780b3e488f4d1f9f",
"assets/analysis-CD4pUStB.js": "46b502ceafca3a706703738eb2c9668c122372c044f356a9b4f1917e2a0dd757",
"assets/app-6koffaPt.js": "b533de49ac430eea916345c561b8e2f7976f2587be418e7cdcd731769c8f7629",
"assets/appearance-dMBBCbrF.js": "0c9cf916a6af943147454967c383468a6cec088bb62e1c974759c6cfbd1e2e1a",
"assets/audit-IKTPV-c0.js": "883bb2a2f9b3907fabdbd7bed0dfda89d7195501e973b40b50db8b458d2ce67c",
"assets/bootstrap-confirmation-zU1pT5Kx.js": "ad084cc139f41712f52503bda58577f51bb9a496374d9b97ed521e25d8689fee",
"assets/business-D6sGcu4f.js": "2bc8caebd0720993421209c3ef5897080ca7a0afcd088c3e7887eaec76f945c4",
"assets/business-interest-DMzRJKcE.js": "c974148f8dbc3ad9a4f85de04aef9a6c9a75c709a543cb478c23ec17e05d2b9e",
"assets/business-marketplace-16_YFmUF.js": "7fb9bda513b10c3ec6da6fca4d6b08de856692b06d9fe7956e679dfe359cab4f",
"assets/business-objects-DuARIRpa.js": "9f3e9f60398babed0cfde3c721434d8ff1c44c6700a17bc40fdccc0fb59f1dfa",
"assets/business-opportunity-BNbAOFL9.js": "bca21b309fe374e132930ac0ab6b7be577146a6d0170579667cabbb05c8428f8",
"assets/business-verifications-2Al7Pg8m.js": "0f0411d457fd46239dd9392ed0af3d1a7a9b21a758caa8477860442ce2a69f13",
"assets/business-wizard-B2JTxZMO.js": "625d88feeb23646ddfe87e6fa957d6ea6b86e2d117683cd097738308aaabc382",
"assets/businesses-HEmaf_kQ.js": "f1242130e283258091208a234575d76dc89ebbf1c2ee3ce6a2373b70bd1b0516",
"assets/case-B3iezsz3.js": "a90338784fa5cea8790a99b6e87a3488120ff1cb1756546fc5e3f25756ae10b4",
"assets/catalog-BwNtwLxB.js": "e315e1684e109b23e6b1359f1dfaeac23e3070308ae46ffaeae2883ac0356932",
"assets/catalogue-BxoE4EAL.js": "78e87674a8d5efd96831186c9ffdf00a1ec71f08df956da8b24ff0b745fb4c8b",
"assets/catalogue-DNWlydH2.js": "3be2af1ff8f22aeab9656aa0c9cb20a24fdef2b58122005250c4e0fde3b528aa",
"assets/catalogue-DzIlCfaf.js": "29da3a5ae2a9017493d014bb4c07873776421855e3f55e3e2f379209bfde96f8",
"assets/confirm-password-DoW48TlT.js": "03a03c5b11075a447be7f0121c17e77bebfc71a8d01c82f4e0a525b825f692e7",
"assets/context-BCjd3hOB.js": "ee0bdab947436992c1c330afcce2b6b5de5f63dee5de5cd21b754ef85c3b757c",
"assets/conversation-Lbuxtg60.js": "ce68c556a91313ba9c285531f261687852daddfb45fd7df43e285d05a3d07b79",
"assets/convert-Cmif6Y0u.js": "961a7b53035f1e6aac6713852edd9a10c36051237c0a90c1ca11fa6badd2c274",
"assets/dashboard-B7H-NvB6.js": "0ad70ac7bb9743d5b45187ef4cc4cf401c04550203797e7fb7104d2abdf65aab",
"assets/dashboard-Bv6vwdLI.js": "620ff25df1a8a3d9da67535cfec4ac8d159006f82f5b39c79736dbdf3276bb36",
"assets/desk-internal-operations-BgotJDzO.js": "bacf4ee9b3b0506218b0b6cf222c89e1ee291c8b35402581d5a314952917a8fb",
"assets/detail-lc1sZGLv.js": "1f3b23fb44758259fb5b2ec6e9babcfb055e822f72a194ce22b06ee75162332e",
"assets/detail-xVTgKqyJ.js": "5690761afeae25a598bae253cd2627c7d9980571ec919b1f3806f69d3ec86bbd",
"assets/dialog-BYzV5tSn.js": "cee51bfbd4bc17f7f4b31f1abd4ce4cc7f3a58e35b61072256d07b4b499b35b6",
"assets/document-BwUuCxkg.js": "7e36ac4f4b8fa6b930d66cc6fcd63991ed47930455a3c3a17bac16d16a008cb3",
"assets/editor-2DyDAvVU.js": "27c4ec0bc20ee4d026028baba909b8a8a41a01c77f4913fe72147bb93a11427b",
"assets/editor-4WTAzpYk.js": "1bd51720aecab997486b3777f134c56d3176c3f4147b9e61b49358d1b6e51d08",
"assets/editor-Czh8O56e.js": "9b84ebd832a595121f58ed9dc7c02e07a73202183b3fca5b1ba2ed85f63549cd",
"assets/education-DPfjwmlA.js": "071410349c531db5be48c34976c6f3fd685ac22b57dd61f20bcab4fba36dc7dd",
"assets/fonts-C9MNnjVw.css": "3846a9bb60bfad92960eadcccaf0b4e129d74b11d48791506c8d1a827a385cc8",
"assets/forgot-password-NuXRKj0-.js": "0a0643d310e85a60e40f5d7ff4b7cb822e794c09d33bbb248ad4e945be91a4de",
"assets/form-BmewvnzL.js": "c4d819355c20014d465af231a448d639f4bf8408f46e99865feed4fe25cd90a7",
"assets/history-BD0biKsC.js": "85c91b9bb6083e85c487b9d55a294ec01c24a841adf7f62fb2d9fb185d2a817f",
"assets/install-BOKZXUPn.js": "9cb97a45cbf94ea827ad311cc641206195f5851acc4dc468c691b3df6509e217",
"assets/installation-CZ_bcFXw.js": "6e99ef762bb7fe7856a3587cc48aaf954686d6626b7cc55182189660ff09bc90",
"assets/installation-CuUS64JQ.js": "abd1ab03350e5f8e76aea6769cff69dfe9376ebc732cc00290641b7b4555b5f4",
"assets/interactive-investment-map-kc25PBcM.js": "4957ebb3aec19a0c4bd47816136c5392bf9a3e94cf74b1b787d0bb3ec4dec15f",
"assets/interest-Dx3i-rDY.js": "6d6db408fa412ff92271af65b011be404063800ac2de82f7dc49f94570dccc01",
"assets/interests-DbjR9rUG.js": "b08683b93a3cff1b202015a2a00c51361c2d326d5077f8e8bf4c078c6672b003",
"assets/investment-map-panel-D4UkHert.js": "95f145375e67c314ccfd5303f2aa3561f8862dd3e7da1b53285c0ca240628a62",
"assets/investment-territory-Bj7E9cdW.js": "4fdb10fc48dbcc36eaf21551b2871413c4a47c7a735110a836fc7f5dfd75e0cd",
"assets/investor-B2RRfbRM.js": "a52f9eea82fbaa26c10a6be8c076d564dabafda5bc9c3f9792afb102e18cd026",
"assets/investors-DO2PHXP6.js": "eb7b592ad06c01720b62b313c558ba2d946008fa476913e97e7fd1dc4f1c8c55",
"assets/lead-BiFql0_x.js": "8f0a58049e7d6c6f6606ec187873f361af5945b4cf6a927eb5cdc12d0f946b76",
"assets/leads-DKvcU0F-.js": "2eeb1d56ac5cf1d3c9087905afa33d1eae5db674c284c1c5ca39d84d62400c64",
"assets/login-pFhq8f0A.js": "7e9912ec9ae8d564ecd96fa00274cea053fef9e2b76aa93d7b347006d3a2351e",
"assets/manage-CEXfP-bD.js": "a1d9c138ebc0bafd2bc3a7b38457b57bae3d94bf74c94c87ced5010ccca5e0fa",
"assets/notifications-D7YtOqH-.js": "14a98ee971b32f48a95784c434437b199209492635608f6a3443bb89b87cccd9",
"assets/opportunities-BeP1nUjV.js": "819e9226bce5365a80c00079d7d5663144a28e0178b7444e58b10911a2580d3a",
"assets/opportunity-draft-DY2xk8f5.js": "e071315aedf9237da3aa34f430816214017a838ad01dadcb1d5c259fa2b29826",
"assets/opportunity-install-LOjhly-M.js": "1d9021852aedf2518a77fb11124ac82a98b02b1aa07d4883c064c1193d07e20b",
"assets/opportunity-origin-P65CBahN.js": "9212b0eac1abaeebca3434dd1778a34a5b62061d544db7c87818ed27290053b4",
"assets/opportunity-resources-f8hcGJe0.js": "44af61f09d42c69864d3ab05a071583c44b89c5b7c21809011d160bc91635747",
"assets/panel-DwBN6cRB.js": "5c3374e5afe87859c24d04145586a4622a8462e064b801fe761fd9e14d10091f",
"assets/passkey-verify-CHbNONJw.js": "811cf0e592bad83b6b2c3ee6f33463aefc0fe9da158e70043a79081d0eef16e7",
"assets/password-input-CZEiv6-Y.js": "6cf06107091b98408d1f8e2eb78c483748ca05e4b6527f10f6d415cc9aacf26f",
"assets/portfolio-BeA7vA21.js": "daf733a04f73f156c02f24250f7776fce51e0bde975a0532593602b6bf2cefb3",
"assets/profile-7FEFpszu.js": "6afac1c5e20cb541be51628f561400caa21eee2e6af566142aea97086ba7ab43",
"assets/profile-json-Bb5H6-rZ.js": "0c4720d8d5baabfcc199d66bc171b014152f3cf2ff40b542d38e86cc1e04a77a",
"assets/profile-kiqG9EDh.js": "b4278437074b9f335a2e70f1c991a704a8ad3578053655561e3f9f6dd05ff3e0",
"assets/references-a6GUerWr.js": "dc0ad799c3a4c5a419d70c98f766e7d4d838733ca661e231924dc5e322af5237",
"assets/register-Dz4XuOsS.js": "4df16cae0d61de9928e19467191b6be173da8995a5c9ad1ca3a296d13a82b596",
"assets/relationship-repair-BbPpEIow.js": "e7c9f476e2a65d9802910a945caed97d741202177d5cbb67c0f48a46e84ca85c",
"assets/request-BnuYhHmw.js": "47eb74e227f0d2dc9a41357f2b4a696daafe4b8dd90b076e945074cbc95c7fc4",
"assets/request-DNLOT7Ur.js": "bfc00723597db137c39f10460b1979af05fa431143633defb9e318763dc77fa8",
"assets/reset-password-FH2pmEDN.js": "fb9e46c168c4e02ae28831fe6b49b51fbd4b1261e8b922f51720444e224a0064",
"assets/result-BaPIoTbf.js": "e55b520c37e0c6d2ffa0f117d434018675f7272e257d252f2fde3c359ec4aea8",
"assets/room-DtK7QZt7.js": "56fa46e93d482c382bb1f5018e52fa7af9e3543a5d565586c04f5eff6f38ab71",
"assets/security-B_oLYs5-.js": "e0f7a12c7869894ba6c2af31a1f8c4ae3b62bbeb825e2d7d6458ec4cbda58627",
"assets/services-BZQcAJGT.js": "1960b184275a312174a31eb30ed3931ee04d25bfa8726b1602caee61a3664f1f",
"assets/shared-BEDl7WFV.js": "75a67b27609c6df591628e9c385b219b2ca7fd8c09358a0eba2fed662bdb6bed",
"assets/shared-CJucoqgO.js": "ee33544fb6f711d44818c5662a3cd186c9761fd7c6614f8eaaee10eb14be3ffb",
"assets/shared-CNf7SPwM.js": "a25ddb63a1ddc8c2f84ca1ba006e55de29d88f6711e4b8fcd1ca6ed9135cb343",
"assets/shared-CXW4I9EU.js": "e69a99b96195fce0f3f96bca7cd1636b6ac860bda13c2917599e8636cd022fc1",
"assets/show-B3_nUTlb.js": "bfaf81cd443ddf447999ef6715ae53bccf3bee44b9052169782a744b40f499a8",
"assets/sources-DqLhX3mx.js": "1066ed12003204175aeb81a08c1ef74d36aaa4b6c58df3313565a27e8051e4b8",
"assets/structure-geography-D0mJ03tA.js": "816a83663ec718609353a0e8d376983e8b751339fa30a67d6e77312af66dd845",
"assets/structures-Bw3yjEkY.js": "4ad7e1a8956deb2d75a245a556de83ef9ff0116226880b9a1530707684eb1ca7",
"assets/submission-BztVPQOB.js": "bbfcb673921e5653c24d0a923d80de5be070d7e8feddcc2505e582e0cfd543db",
"assets/territory-associations-BghnoFKh.js": "1c5a852fe02917a109a6b046409d0a07fd7e4ab15ca7e7cb5543a2c1f0ca774c",
"assets/territory-geometry-import-BgUiqJjl.js": "a2dff089e300e59db3692a582575bf77da407646c04720701c3eeabf88a1acb7",
"assets/territory-geometry-preview-DqO4V0-r.js": "7af32d2f6347d59e5c93779caa86153853f352dcce89f2b4dc2bd6a47713f024",
"assets/two-factor-challenge-C-j2ixF_.js": "eac048f285e5dfd3daab2fe4ba6891087a8068547aa2dd1f0865e761938b0efb",
"assets/value-network-Bw5_SMDf.js": "cb1648f4d2839bb93211426c8ce9eac9e5414648d6728ffbbf0e94bcd7e47afa",
"assets/verify-email-DGF0VDk6.js": "2bfe6141b58c741a570d9f5f9e0af73a7f045509203fe8d360e550b7613109a7",
"assets/welcome-CPCJPF06.js": "d622fed9d44676a1243143766cd2849cff89354dc4ab610a74921feadd357807",
"assets/workspace-Bo7B3eQ-.js": "2663a517177c1caafd6ce35ea5fbcbed97c3a0a01bcb8785b1576a8604a7b4f5",
"assets/workspace-CtTfcNTT.js": "a780023d248ea787dfacba88b97f40124c8e00c43ba98d3c358eea48a79ed227",
"assets/zone-H5olHugq.js": "d68e37fd62695b903544352c77817bcab468710f2e073c3c4c0ed54db5ec594c",
"assets/zone-attachments-CANe4XzA.js": "af0f90d0f9ca0c5f382e3a459e42c2d2d2213bbcd1517e2234da684acd1f34c7",
"assets/zone-map-DKg4YJ5O.js": "b4de181ae51a74c1f0b36d9c93f98adfd0a45074fad2259923184508597d41e2",
"assets/zone-relations-D-lZGYpC.js": "b189b5ed4a6787a457c804350234d25523d691e3f6b4f1219fc61323874cf5bc",
"assets/zones-PkKrJeXJ.js": "4d1280a4de3116ca6650a8f506a1e6489dc7bfe73251092dda4adb0bba9bb4c4"
},
"fonts_dependency_already_in_base_ZIP": true,
"dependency_lockfiles_equal": {
"composer.lock": true,
"package-lock.json": true,
"vendor/composer/installed.json": true
},
"flags_read_only": {
"INVESTOR_PATH_ENABLED": "absent; use configuration default",
"VIRTUAL_DESK_ENABLED": "absent; use configuration default",
"PORTAL_ORGANIZATION_COUNTRY_ENABLED": "true",
"PORTAL_PROFILE_ENABLED": "absent; use configuration default",
"PORTAL_PROFILES_ENABLED": "absent; use configuration default",
"PORTAL_OPPORTUNITY_WORKFLOW_ENABLED": "absent; use configuration default"
},
"migration_dependency": {
"file": "database/migrations/2026_10_09_190000_prepare_investor_path.php",
"sha256": "939c2b2e5f9fd6a454fe7f8dd4f4373fd7df53f80e5c5f169db08e6e4c676728",
"columns_missing": {
"investor_journeys.path_definition_id": {
"table_schema": "public",
"table_name": "investor_journeys",
"column_name": "path_definition_id",
"ordinal_position": 18,
"data_type": "uuid",
"udt_name": "uuid",
"is_nullable": "YES",
"column_default": null
},
"journey_steps.path_detail": {
"table_schema": "public",
"table_name": "journey_steps",
"column_name": "path_detail",
"ordinal_position": 14,
"data_type": "text",
"udt_name": "text",
"is_nullable": "YES",
"column_default": null
}
},
"installed_in_restored_QA": true,
"installed_in_destination": false,
"existing_authenticated_installer": "GET/POST https://portal-investidor.test/management/balcao-install",
"no_generic_migrate_or_SQL_bypass": true
},
"inherited_scope_discrepancy": {
"id": "C137",
"source": "resources/js/pages/partnerships/room.tsx",
"destination_sha256": "43b64ce253bf450888fcd3b10d5e5860cc2633aed29a82cde965d82ae99172e3",
"QA_source_sha256": "fea8a156ee7ff8b24492ec0bfe5e61ab4d6ecefe588f65bec67909fc704df53a",
"present_in_original_base_compiled_bundle": true,
"present_in_current_candidate_compiled_bundle": true,
"included_in_35_source_delta": false,
"behavior": "UI permite ao autor retirar partilha existente após encerrar sala; bloqueia novas partilhas.",
"approved_B_scope": "salas/C137 fora do loteB; não inferir aceitação ou autorização de ativação",
"new_code_written_in_this_task": false,
"resolution": "Manter candidata imutável; exigir decisão expressa da Tempo antes de ativar bundle com esta diferença. Não substituir silenciosamente por outra compilação."
},
"operational_activation_ready": false,
"reasons": [
"Migração190000 existente ausente do destino; instalação autenticada e flag são ações separadas ainda não autorizadas.",
"C137 herdado do bundle base está fora do âmbitoB e fora do delta35; requer delimitação expressa antes de ativar."
],
"active_changes": 0
}
@@ -0,0 +1,120 @@
{
"at": "2026-10-15T13:08:40+00:00",
"clone": "b_final_restore_20261015_124723_test",
"port": 55441,
"destination_schema_equal_to_clone": false,
"destination_migrations_equal_to_clone": false,
"destination_column_count": 1970,
"clone_column_count": 1972,
"clone_only_columns": {
"investor_journeys.path_definition_id": {
"table_schema": "public",
"table_name": "investor_journeys",
"column_name": "path_definition_id",
"ordinal_position": 18,
"data_type": "uuid",
"udt_name": "uuid",
"is_nullable": "YES",
"column_default": null
},
"journey_steps.path_detail": {
"table_schema": "public",
"table_name": "journey_steps",
"column_name": "path_detail",
"ordinal_position": 14,
"data_type": "text",
"udt_name": "text",
"is_nullable": "YES",
"column_default": null
}
},
"destination_only_columns": [],
"changed_columns": [],
"clone_migration_names": [
"0001_01_01_000000_create_users_table",
"0001_01_01_000001_create_cache_table",
"0001_01_01_000002_create_jobs_table",
"2024_01_01_000000_create_passkeys_table",
"2025_08_14_170933_add_two_factor_columns_to_users_table",
"2026_01_01_000001_create_sectors_table",
"2026_01_01_000002_create_opportunities_table",
"2026_01_01_000003_create_interest_requests_table",
"2026_09_24_000100_investmoz_extensions_functions",
"2026_09_24_001000_investmoz_identity",
"2026_09_24_002000_investmoz_content",
"2026_09_24_003000_investmoz_geography",
"2026_09_24_004000_investmoz_projects",
"2026_09_24_005000_investmoz_clusters",
"2026_09_24_006000_investmoz_corridors",
"2026_09_24_007000_investmoz_crm",
"2026_09_24_008000_investmoz_journey_aftercare",
"2026_09_24_009000_investmoz_education",
"2026_09_24_009500_investmoz_document_links",
"2026_09_24_010000_investmoz_governance_ai",
"2026_09_24_011000_investmoz_integrations",
"2026_09_24_012000_investmoz_indexes",
"2026_09_24_013000_investmoz_triggers",
"2026_09_25_100000_extend_crm_intake",
"2026_09_25_110000_create_investment_gaps",
"2026_09_25_120000_add_interest_submission_receipts",
"2026_09_25_130000_investment_portfolio_journeys",
"2026_09_26_100000_education_intake",
"2026_09_26_110000_education_investment_proposals",
"2026_09_26_120000_investmoz_ai_foundation",
"2026_09_26_140000_portfolio_owner_approval",
"2026_09_27_120000_public_portal_services",
"2026_09_27_140000_investment_unification",
"2026_09_27_150000_investor_workspace",
"2026_09_28_090000_version_investment_dossiers",
"2026_09_28_100000_investment_zone_foundation",
"2026_09_28_110000_zone_geometry_review",
"2026_09_28_120000_investment_submission_zones",
"2026_09_28_130000_existing_business_foundation",
"2026_09_28_140000_existing_business_intake",
"2026_09_28_150000_territorial_registry",
"2026_09_28_160000_investment_primary_territory",
"2026_09_29_100000_territory_integrity",
"2026_09_29_200000_existing_business_form_sector",
"2026_09_30_100100_skills_education_1",
"2026_09_30_100200_skills_education_2",
"2026_09_30_100300_skills_education_3",
"2026_09_30_100400_skills_education_4",
"2026_09_30_100500_skills_education_5",
"2026_09_30_100600_skills_education_6",
"2026_09_30_110000_project_dependency_integrity",
"2026_09_30_120000_extend_existing_business_marketplace",
"2026_10_01_000100_create_reference_catalogs",
"2026_10_01_000200_create_simulation_execution_core",
"2026_10_01_120000_create_simulation_form_drafts",
"2026_10_02_120000_allow_owner_to_read_soft_deleted_simulation_drafts",
"2026_10_02_160000_extend_existing_business_opportunity_types",
"2026_10_03_170000_create_simulation_tax_rule_governance",
"2026_10_03_180000_govern_investment_structure_relations",
"2026_10_03_190000_allow_public_read_of_published_tax_parameters",
"2026_10_03_200000_create_land_assistance_cases",
"2026_10_03_210000_make_interest_request_email_nullable",
"2026_10_04_120000_add_opportunity_geography_scope",
"2026_10_04_120000_add_simulation_draft_continuity",
"2026_10_04_130000_extend_investment_zone_records",
"2026_10_04_140000_create_investment_zone_attachments",
"2026_10_04_150000_relax_zone_operator_publication_requirement",
"2026_10_04_160000_extend_zone_development_and_area_scopes",
"2026_10_05_120000_extend_portal_document_catalogue",
"2026_10_05_130000_add_document_malware_scanning",
"2026_10_06_140000_allow_unapproved_private_portal_resources",
"2026_10_06_180000_add_document_applicability_dates",
"2026_10_06_200000_add_document_requirement_evidence_links",
"2026_10_06_210000_allow_informational_zone_publication_without_second_publisher",
"2026_10_06_220000_add_company_purchase_business_modality",
"2026_10_07_160000_extend_internal_partnership_exchange",
"2026_10_07_190000_create_internal_virtual_desk",
"2026_10_08_120000_extend_desk_investor_guidance",
"2026_10_09_020000_extend_opportunity_management",
"2026_10_09_030000_extend_opportunity_resources",
"2026_10_09_190000_prepare_investor_path",
"2026_10_10_040000_create_portal_profile_authorization",
"2026_10_10_050000_extend_organization_country"
],
"new_migrations_in_candidate": 0,
"active_changes": 0
}
@@ -0,0 +1,45 @@
{
"at": "2026-10-15T13:06:20+00:00",
"candidate": "B-final-fabf722bc8c6",
"restore_target": {
"database": "b_final_restore_20261015_124723_test",
"port": 55441
},
"DB_read_only": true,
"application_base_is_private_clone": true,
"candidate_source_and_bundle_from_restored_files": true,
"shared_vendor_dependency": "C:\\laragon\\www\\portal-investidor\/storage\/app\/private\/investmoz-v2\/portal-audit\/portal-stability-source-20261011_083742\/vendor",
"kernel_bootstrap": "passed",
"HTTP_kernel_routes": [
{
"method": "GET",
"path": "\/up",
"status": 200,
"body_bytes": 1757,
"body_sha256": "0e5f4ba27dfb22f477127fb7e6a45085f7f3e8cce5b541f99f785cd00751aaf0"
},
{
"method": "GET",
"path": "\/login",
"status": 200,
"body_bytes": 7743,
"body_sha256": "0ef3e76f37e9911f0204fb0ddfd8a690c886d66d6f74cf7d4bb3e00159e738e4"
},
{
"method": "GET",
"path": "\/oportunidades",
"status": 200,
"body_bytes": 209717,
"body_sha256": "91793ed7b3f195cb9db576feb9bb5c229060a0e2111110c364b60ed5f5c04185"
}
],
"model_read_in_restored_database": true,
"view_rendering_and_Vite_manifest": "passed",
"SSRandExternalConnectorsDisabled": true,
"session_and_cache": "array in clone only",
"database_changes": 0,
"active_changes": 0,
"functional_12_criteria_repeated": false,
"real_web_server_TLS_worker_boot_test": false,
"activation_authorized": false
}
@@ -0,0 +1,48 @@
<?php
use App\Services\InvestorPathDefinition;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
public function up(): void
{
if (! app()->environment('testing') && ! config('investor-path.authenticated_installation')) {
throw new RuntimeException('Investor path installation requires an authenticated, verified activation plan.');
}
if (DB::connection()->getDriverName() !== 'pgsql') {
throw new RuntimeException('Investor path requires PostgreSQL.');
}
DB::statement('ALTER TABLE investor_journeys ADD COLUMN path_definition_id uuid REFERENCES questionnaire_versions(id) ON DELETE RESTRICT');
DB::statement('ALTER TABLE journey_steps ADD COLUMN path_detail text');
$definition = InvestorPathDefinition::snapshot();
InvestorPathDefinition::validate($definition);
$existing = DB::table('questionnaire_versions')->where('id', config('investor-path.definition_id'))->first();
if ($existing) {
$stored = json_decode($existing->schema_snapshot, true, 512, JSON_THROW_ON_ERROR);
if (! is_array($stored) || Arr::sortRecursive($stored) !== Arr::sortRecursive($definition) || $existing->code !== 'investor-path-19' || $existing->status !== 'published') {
throw new RuntimeException('Published definition differs: create a new version rather than overwrite it.');
}
} else {
DB::table('questionnaire_versions')->insert([
'id' => config('investor-path.definition_id'), 'code' => 'investor-path-19', 'version_no' => 1,
'locale' => 'pt-MZ', 'schema_snapshot' => json_encode($definition, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE),
'status' => 'published', 'valid_from' => '2026-10-09',
]);
}
// Definition availability does not enable the feature or reinterpret existing journeys.
}
public function down(): void
{
if (DB::table('investor_journeys')->whereNotNull('path_definition_id')->exists()
|| DB::table('journey_steps')->whereNotNull('path_detail')->exists()) {
throw new RuntimeException('Preserve investor path history: disable feature or restore a verified backup instead of dropping used columns.');
}
DB::statement('ALTER TABLE journey_steps DROP COLUMN path_detail');
DB::statement('ALTER TABLE investor_journeys DROP COLUMN path_definition_id');
// Published questionnaire versions are immutable; retain the unused definition and its provenance.
}
};
@@ -0,0 +1,86 @@
{
"at": "2026-10-15T13:11:11.250317+00:00",
"candidate_revision": "B-final-fabf722bc8c6",
"candidate_ZIP_SHA256_unchanged": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"kind": "Suplemento operacional; candidata e aceitação mantidas",
"boot_passed": true,
"destination_read_only": true,
"active_changes": 0,
"12_criteria_repeated": false,
"activation_authorized": false,
"activation_ready": false,
"operational_gaps": [
"Migração190000 existente ausente do destino; instalação autenticada e flag são ações separadas ainda não autorizadas.",
"C137 herdado do bundle base está fora do âmbitoB e fora do delta35; requer delimitação expressa antes de ativar."
],
"all_candidate_and_base_archives_verified": true,
"Vite_and_font_dependency_closure_verified": true,
"dependency_assets_available": 273,
"files": [
{
"file": "LEIA-ME.md",
"bytes": 493,
"sha256": "cba79fbf260da16cdc98209f1ec41f8aa95d8f7eab658cddf48a53a5621e8c14"
},
{
"file": "PROCEDIMENTO-EXATO.md",
"bytes": 6621,
"sha256": "dae9afca948cafb8f62234dbf97a222c3d527a742e27de377880d6c7b7220cd6"
},
{
"file": "PROPOSTA-UNICA-TEMPO.md",
"bytes": 1625,
"sha256": "4ceae8c000117d67fe9f4a884bf3c8cd442e3ad793840f381d946d729801ae05"
},
{
"file": "candidata/investmoz-opcao-B-candidata-final-revisao-20261015-fabf722bc8c6.zip",
"bytes": 7771394,
"sha256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78"
},
{
"file": "evidencias/B-boot-base-assets-20261015.json",
"bytes": 3988,
"sha256": "dd165edc382a0d221d5dd112022626aa5f573306ece9b9b81a7a9ee7dc2037fd"
},
{
"file": "evidencias/B-destination-preflight-readonly-20261015.json",
"bytes": 745394,
"sha256": "7674a0084f8c18a6ef18d21a89ca6d539523c5d7ab0c09e15a5511e6dd3524f2"
},
{
"file": "evidencias/B-exact-deployment-map-20261015.json",
"bytes": 52011,
"sha256": "1c1c0bf81cf5087561aea711855f66fd65a5e747425d61dc8d7e69f751fd9ebd"
},
{
"file": "evidencias/B-final-backup-restoration-20261015.json",
"bytes": 1072,
"sha256": "8ea27dcd498fe887f6a615941ddb64072738b1c3c682a84839deffbc49865b3f"
},
{
"file": "evidencias/B-final-package-verified-20261015.json",
"bytes": 723,
"sha256": "8c8200f2fb64c5d291205aa451cd82db0dd3ad43c2484f78d94e997d96ae7d0d"
},
{
"file": "evidencias/B-operational-dependencies-20261015.json",
"bytes": 14081,
"sha256": "0a43f010902c6c78c2bdaa680db6d4b4749f2b60ddbc21d3180c83b6585269a9"
},
{
"file": "evidencias/B-operational-schema-readonly-20261015.json",
"bytes": 5916,
"sha256": "6a54399850c25280feda047c341bd33f1226f14389e5020ea94b5eb891c57c55"
},
{
"file": "evidencias/B-restored-clone-boot-20261015.json",
"bytes": 1653,
"sha256": "7744a5e941bef358e9b027fae036a8f2bd708d2e34c017add73d119291119ca9"
},
{
"file": "evidencias/migracao-existente-190000-referencia.php",
"bytes": 2693,
"sha256": "939c2b2e5f9fd6a454fe7f8dd4f4373fd7df53f80e5c5f169db08e6e4c676728"
}
]
}
@@ -0,0 +1,39 @@
# Disponibilização/reversão — procedimento exato preparado, não executado
Candidata imutável **B-final-fabf722bc8c6**; ZIP SHA256 `c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78`. Destino lido: `C:/laragon/www/portal-investidor`, `https://portal-investidor.test`, `investemoz:5432`, snapshot 2026-10-15T13:07:07+00:00. PHP Apache8.5.11/Apache2.4.54; configuração sem cache e DevToolsOFF. Dependências Composer/NPM/installed.json iguais às do ensaio. Matriz exata de35 fontes e173 recursos: `B-exact-deployment-map-20261015.json`; inventário atual769 recursos: preflight. Nada abaixo foi executado no destino.
## Portas de entrada obrigatórias
1. **Não ativar sem autorização explícita da janela e decisão de inclusão ou separação de C137.** A migração existente 190000 é dependência de instalação já prevista para o percurso integrado B, não requisito novo ou decisão de âmbito. C137 está herdado no bundle mas fora do âmbito B. Os 12 critérios mantêm-se encerrados; não trocar/recompilar candidata silenciosamente.
2. Depois de autorização específica e janela, executar verificação local dos hashes do ZIP, manifesto,35 fontes anteriores,769 recursos atuais, `.env`, config/inertia.php e locks. Se o destino tiver divergido do preflight, parar antes de qualquer troca e atualizar o mapa somente por leitura. Conferir mais uma vez identidade SQL investemoz:5432; nunca usar contas/grants/documentos QA no ativo.
3. Renovar backup consistente **do destino atual**, originais/cifras/configuração/ACLs e metadados, para diretório privado fora do webroot; restaurar em novo clone55441*_test e verificar. O backup QA já verificado não substitui este backup do destino; o backup de código atual preparado é `C:\Users\macbook\.config\investmoz\B-final-recovery-20261015_124723\destination-before-activation`. Não usar o dumpQA como rollback do ativo. Só iniciar a janela após recibo do backup/restauro fresco do destino.
## Sequência futura após autorização
4. Na raiz do destino, com `C:/laragon/bin/php/php-8.5.11-Win32-vs17-x64/php.exe`, usar `artisan down --retry=60` durante a troca; não criar endpoint de reset/segredo de bypass. Não tocar em workers/filas/ClamD/CA por este lote. Preservar flags eDevToolsOFF. Não executar `composer install`, `npm build`, `migrate`, `migrate:fresh` ou instaladores030000/040000/050000.
5. Na janela explicitamente autorizada da opção B integrada, para satisfazer a dependência 190000 já prevista, preparar primeiro as provas frescas do código final/destino nos controlos existentes e usar utilizador real já autorizado manage-portal com MFA em `GET /management/balcao-install`; conferir preview/hash e pendência **somente2026_10_09_190000_prepare_investor_path**. A aplicação idempotente ocorre pelo `POST` do próprio formulário, com CSRF e hash exibido, nunca por SQL direto/configuração de bypass. O serviço conserva as migrações anteriores e adiciona apenas investor_journeys.path_definition_id, journey_steps.path_detail e definição publicada imutável; não converte dossiers. Se backupVerified/qaVerified/pathQaVerified/compatibilityVerified/databaseReady não passarem para o código/destino final, parar; não fabricar readiness nem repetir os12 ensaios para contornar o gate. Instalação não habilita navegação: `INVESTOR_PATH_ENABLED` requer autorização específica separada na mesma decisão de ativação, caso a entrega integrada seja escolhida.
6. Extrair o ZIP para staging privado. Montar a compilação base de `historico/investmoz-B-base-396c691930bc.zip` e sobrepor `compilacao-QA` da candidata; manter fontesCSS/fontes e recursos anteriores. Copiar apenas os35 caminhos de fonte do mapa, verificando before/after e preservando ACLs do destino. Para recurso de nome com hash já existente, só reutilizar bytes iguais; colisão divergente interrompe a operação. **Não eliminar os769 recursos atuais.** Selecionar `public/build/manifest.json` por troca de ficheiro no mesmo volume apenas depois de fontes/recursos íntegros; copiar fonts-manifest correspondente e conservar os ativos da base que referencia. Não extrair o ZIP histórico por cima de código/configuração do destino.
7. `artisan view:clear` apenas para views compiladas, `artisan up` no fim. Não executar optimize:clear, cache:clear ou limpar sessões/filas de aplicação por conveniência. Apache configurado carrega PHP8.5.11 por mod_php; não confundir PHPCLI com PHPweb. Se necessário invalidar OPcache, usar mecanismo administrativo existente/reload gracioso do **Apache ativo** `C:/laragon/bin/apache/httpd-2.4.54-win64-VS16/bin/httpd.exe -k graceful -d C:/laragon/bin/apache/httpd-2.4.54-win64-VS16 -f C:/laragon/bin/apache/httpd-2.4.54-win64-VS16/conf/httpd.conf`, somente com autorização da janela e após teste de configuração; não reiniciar instânciasQA nem editar php.ini. Não foi afirmada necessidade de reload nesta preparação.
8. Conferência operacional pós-troca limitada a hashes, PHPweb/HTTPS, `/up`, `/login`, carregamento do bundle/fontes e logs de arranque; login/MFA normal sem reenviar códigos, se necessário à observação operacional. Não refazer os12 critérios nem alterar registos aceites. Registar recibo final do destino, janela e autor. Qualquer erro500, ativo404, hash divergente, exposição de diagnóstico ou dependência não resolvida exige contenção/reversão, não prosseguimento automático.
## Reversão futura
9. Se houver regressão, manter/entrar manutenção; não executar down de migrações usadas. Repor apenas as35 fontes originais presentes no diretório privado indicado e manifesto/font-manifest anteriores, pelos hashes before do mapa. Caminho originalmente ausente só pode ser retirado se ainda tiver exatamente o hash da candidata, sem apagar alterações posteriores. Recursos adicionados podem permanecer inertes; não apagar arquivos por varrimento. Repor views compiladas por view:clear, verificar HTTPS/arranque, sair da manutenção.
10. Se190000 tiver sido instalado e já tiver histórico, preservar duas colunas, definição e dados; desabilitar apenas a flag cuja mudança foi autorizada e registada na janela. Não repor `.env` antigo inteiro se outras alterações tiverem ocorrido; manter COUNTRY02, workflow/perfis eDevToolsOFF. Reversão de código não recupera a autorização PromotorQA22 nem afeta publicaçãoQA v12. Restauração integral do destino só por decisão adicional, backup próprio verificado e reconciliação dos dados posteriores. Nunca importar o cloneQA.
Esta preparação não executou manutenção, instalação, alteração de flag, cópia para o destino, limpeza, reload ou restauro ativo. Os comandos são roteiro futuro sujeito aos gates acima.
## Efeitos exatos e aplicação somente do ausente
190000 acrescenta `investor_journeys.path_definition_id uuid NULL REFERENCES questionnaire_versions(id) ON DELETE RESTRICT` e `journey_steps.path_detail text NULL`. Insere a definição publicada `investor-path-19`/versão1/pt-MZ/ID61000919-0000-4000-8000-000000000001 somente quando ausente; se existente, exige mesmo código, estado publicado e snapshot igual, sem o sobrescrever. Regista somente a migração ausente. Não converte dossiers ou etapas existentes nem habilita navegação por efeito da instalação.
O formulário existente de instalação envia o hash de preview e a confirmação normal por sessão autenticada/CSRF. O serviço usa transação e advisory lock, revalida a pré-visualização e percorre apenas migrações pendentes. Para o destino inventariado, as duas anteriores de VirtualDesk já constam e somente190000 falta. Se uma coluna existir parcialmente sem registo de migração, parar para reconciliar o estado por leitura: não executar a migração à força. Sem `migrate` genérico, flag de autorização por CLI ou SQL manual. Os requisitos de backup e correspondência de provas ao código final são verificações de instalação existentes, não novo requisito funcional.
C137 deve seguir a deliberação da proposta anexa. Inclusão: fonte room.tsx e bundle coerentes, suplemento de manifesto/hash, limitação visual identificada; separação: pacote técnico de compilação segregado, preservando a candidata original. Nesta preparação não foi executada inclusão nem separação. Reversão restaura a interface/build anteriores, preservando decisões de revogação e documentos; não usar rollback para voltar a conceder partilhas.
## Momento do backup e situação atual
O backup/restauro fresco do destino será preparado próximo da execução, depois da decisão concreta e antes da primeira escrita da janela. Não foi antecipado nesta revisão documental. O backup local de fontes/bundle já inventariado é apenas uma referência de reversão por hash; deve ser revalidado na janela e não substitui o backup fresco da base e dos recursos do destino.
Arranque no clone: pendência operacional encerrada. Doze critérios funcionais: encerrados. Dependência190000: aplicar apenas o ausente na futura janela autorizada. C137: decisão de âmbito pendente. Esta mensagem/documentação não autoriza ativação.
@@ -0,0 +1,37 @@
# Proposta única à Tempo — opção B e decisão sobre C137
**Para decisão, sem autorização de ativação nesta mensagem.** Manter a candidata `B-final-fabf722bc8c6` e os 12 critérios aceites, incluindo a limitação documental da linha 07. O arranque no clone restaurado encerrou a pendência de recuperação operacional. Não se propõe nova auditoria nem repetição dos percursos.
## 190000 — dependência de instalação já prevista
A migração `2026_10_09_190000_prepare_investor_path` integra o percurso da opção B; não é requisito novo nem decisão de alargamento de âmbito. No destino lido, faltam exatamente:
- `investor_journeys.path_definition_id`: UUID opcional, com referência a `questionnaire_versions(id)` e `ON DELETE RESTRICT`.
- `journey_steps.path_detail`: texto opcional.
- O registo desta migração e, quando ainda ausente, a definição imutável `investor-path-19`, versão 1, pt-MZ, identificador `61000919-0000-4000-8000-000000000001`, publicada com início em 09/10/2026.
O instalador valida a definição existente: se já estiver igual, preserva-a; se divergir, recusa substituí-la. Não converte dossiers nem renumera etapas. A instalação não liga automaticamente `INVESTOR_PATH_ENABLED`.
Numa futura janela autorizada, usar a ação autenticada existente `GET/POST /management/balcao-install`, com conta real já habilitada a `manage-portal`, MFA, CSRF e hash da pré-visualização. O serviço aplica apenas migrações ausentes; a pré-visualização deve indicar somente 190000. Não reinstalar 030000/040000/050000 nem executar SQL direto ou `migrate` genérico. Preservar os controlos de backup, correspondência da versão e permissões, reutilizando as provas aceites em vez de criar outro ensaio.
## C137 — decisão de inclusão expressa ou separação
**Problema corrigido:** numa sala encerrada/cancelada, a interface escondia o botão de retirar partilha, embora o servidor já permitisse ao autor revogar uma partilha existente. A correção mostra esse controlo ao autor quando o documento continua partilhado e explica o estado da sala. Novas partilhas em sala encerrada continuam recusadas; as permissões do servidor não foram ampliadas.
**Ficheiros envolvidos:**
- Fonte QA: `resources/js/pages/partnerships/room.tsx`; hash anterior/atual do destino `43b64ce253bf450888fcd3b10d5e5860cc2633aed29a82cde965d82ae99172e3`; hash QA corrigido `fea8a156ee7ff8b24492ec0bfe5e61ab4d6ecefe588f65bec67909fc704df53a`.
- Bundle da candidata: `public/build/assets/room-LM3pUYAr.js` e referências em `public/build/manifest.json`/chunks importados. A alteração já existia na compilação base, no chunk `room-DtK7QZt7.js`. O destino usa `room-B9wM3cp1.js`.
- A fonte `room.tsx` não está entre as 35 fontes do delta B. Incluir C137 exige entregar essa fonte coerente com o bundle e identificá-la em suplemento de manifesto, sem alterar silenciosamente a candidata. Separar C137 exige preparar compilação coerente sem a correção, com revisão/hash próprios; não basta trocar um chunk manualmente. Nenhuma destas opções foi executada.
**Provas existentes, sem novos testes:** `C137-QA-delta.json` identifica causa, âmbito e hashes; `C137-build-QA.json` regista TypeScript e build com saída 0, ativos anteriores preservados e troca de manifesto QA. `partnership-revocation-closed-room-revocation-HTTP.json` demonstra, na sala sintética 2/anexo 4: autor revoga após cancelamento; destinatário nas sessões anterior e nova recebe 404; original do autor continua 200/hash igual; revogação repetida mantém o estado; nova partilha recebe 409; não autor/não participante recebem 403 e anónimo 401. A sala 1 permaneceu intacta.
**Limite da prova:** o build não equivale a aceitação visual. A evidência C137 existente declara `visual_observed=false` e aceitação visual pendente; os 12 critérios B não são usados para a encerrar. A Tempo pode decidir incluir expressamente a correção com esta limitação identificada ou mantê-la separada. Isto não pede outra auditoria nem autoriza novos ensaios.
**Reversão de C137, se incluído:** conservar fonte e compilação anteriores do destino; repor a fonte anterior e o conjunto coerente de build/manifestos selecionado antes da janela. Manter os recursos antigos disponíveis. Não recriar partilhas retiradas, não repor ACLs/dados a partir de QA e não alterar a regra do servidor. A reversão da interface volta a ocultar o controlo, mas não deve invalidar uma revogação já registada. Reversão integral da base exige decisão separada.
## Decisão concreta solicitada
Deliberar **inclusão expressa de C137 com a limitação de prova acima ou separação**, mantendo a opção B aceite e 190000 como dependência prevista. Após essa decisão, fixar o complemento técnico correspondente e propor/executar a janela apenas com autorização explícita. Preparar o backup/restauro fresco do destino próximo dessa execução, não agora. O snapshot QA não substitui esse backup.
A candidata original e o seu hash ficam preservados. Não houve ativação, instalação no destino, alteração de flags ou novos testes funcionais.
@@ -0,0 +1,32 @@
{
"at": "2026-10-15T14:52:39.873885+00:00",
"purpose": "Recibo de integridade dos documentos para decisão da Tempo",
"candidate_revision": "B-final-fabf722bc8c6",
"candidate_original_SHA256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"candidate_original_bytes_unchanged": true,
"previous_complete_operational_ZIP_SHA256": "2f68f0410bed011c0aab14700a7c6fee9b460540e8ad0dbf9d30b1c4b7691f46",
"previous_complete_operational_ZIP_rechecked": true,
"documents": {
"PROPOSTA-UNICA-TEMPO.md": {
"bytes": 5218,
"SHA256": "62baeee94807c4fe67d1e8d7178b8dc9e78b323b4d73b622eea4228d6a291c2d"
},
"PROCEDIMENTO-EXATO.md": {
"bytes": 9263,
"SHA256": "92846634655beb75259e0e2b5817883212bc028cce851c42bea9fa43c860bf7a"
}
},
"existing_C137_evidence": {
"C137-QA-delta.json": "ec648d2ffda06681f88510007615cb7ce92f968af7b429b11107a470b3bf8f0e",
"C137-build-QA.json": "0463e05081af50e4e11c9dea3f72fa0a84553245d27184996a45f4359d445a09",
"partnership-revocation-closed-room-revocation-HTTP.json": "ad485d3ece8350925962ff380ef1498ad365d2610bdcd7b1ddfe29d03a8d3439"
},
"clone_boot_recovery_pending": false,
"twelve_criteria_closed": true,
"functional_tests_repeated": false,
"190000": "existing installation dependency, absent-only authenticated action",
"C137": "outside B; explicit inclusion or separation decision pending; visual evidence limitation retained",
"fresh_destination_backup": "prepare close to execution; not performed in this documentary update",
"activation_authorized": false,
"active_changes": 0
}
@@ -0,0 +1,2 @@
<?php
$p=__DIR__.'/B-activation-installed-20261015.json';$v=json_decode(file_get_contents($p),true,512,JSON_THROW_ON_ERROR);$v['at']='2026-10-15T15:27:38+00:00';$v['path_enabled']=false;$s=json_encode($v,JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR);$expected=json_decode(file_get_contents(__DIR__.'/B-activation-flag-20261015.json'),true)['installed_evidence_sha256'];if(hash('sha256',$s)!==$expected)throw new RuntimeException('Receipt reconstruction mismatch');file_put_contents(__DIR__.'/B-activation-installed-before-flag-20261015.json',$s);echo 'Pre-flag receipt preserved with original hash';
@@ -0,0 +1,25 @@
import json,hashlib,pathlib,shutil,datetime
root=pathlib.Path.cwd(); out=root/'outputs/investmoz-audit-current-20261012'; audit=root/'storage/app/private/investmoz-v2/portal-audit'; dest=root/'storage/app/private/virtual-desk'
def read(p):return json.loads(p.read_text(encoding='utf-8-sig'))
def sha(p):return hashlib.sha256(p.read_bytes()).hexdigest()
def write(p,v):p.write_text(json.dumps(v,indent=2,ensure_ascii=False)+'\n',encoding='utf-8')
b=read(out/'B-activation-fresh-backup-20261015.json'); private=pathlib.Path(b['private_directory']); preview=read(out/'B-active-installer-preview-20261015.json'); fingerprint=preview['code_hash']; assert fingerprint==read(out/'B-activation-expected-fingerprint-20261015.json')['expected_QA_fingerprint']
ui=read(audit/'investor-ab-chromium-20261010.json'); persistence=read(audit/'investor-ab-remaining-persistence-qa.json'); compat=read(audit/'investor-path-compatibility.json')
assert ui['result']=='passed' and all(ui['checks'].values());assert persistence['result']=='passed_read_only_existing_path';assert compat['unused_down_and_transaction_restore_verified'] and compat['final_unused_down_rechecked'] and compat['changed_original_tables']==[]
assert b['restore_verified'] and b['restored_table_hashes_equal'] and b['files_verified']
backup=read(private/'backup-proof-private.json'); assert sha(pathlib.Path(backup['dump_path']))==backup['sha256'];assert sha(pathlib.Path(backup['files_path']))==backup['files_sha256']
now=datetime.datetime.now(datetime.timezone.utc).isoformat()
refs=[out/'B-activation-Tempo-authorization-20261015.json',out/'B-activation-fresh-backup-20261015.json',out/'B-activation-file-switch-20261015.json',out/'acceptance-396c-results.json',out/'B-restored-clone-boot-20261015.json',audit/'investor-ab-chromium-20261010.json',audit/'investor-ab-remaining-chromium-20261010.json',audit/'investor-ab-remaining-persistence-qa.json',audit/'investor-path-http-qa.json',audit/'investor-path-compatibility.json',out/'B-suplemento-C137-sequencia-final-20261015/COMPATIBILIDADE-ESTADO-INTERMEDIO.json']
chain=[{'path':str(p.relative_to(root)).replace('\\','/'),'sha256':sha(p)} for p in refs]
common={'code_hash':fingerprint,'reconciled_at':now,'method':'Reconciliation of accepted existing QA evidence to immutable authorized candidate; no new functional test and no re-dating of historical tests. Fresh destination backup/restoration verified separately.','evidence':chain,'limitations':['C137: technical evidence; no specific visual acceptance.','Intermediate state without 190000: code inspection and previous evidence, no new HTTP trial.','Line07 correction request nonspecific: documentary limitation accepted by Tempo.']}
old=private/'installer-proofs-before';old.mkdir(exist_ok=True)
for name in ['backup-proof.json','guidance-qa-evidence.json','activation-compatibility.json','investor-path-qa-evidence.json']:
p=dest/name
if p.exists():shutil.copy2(p,old/name)
qa={**common,'passed':True,'database':'stability_consumers_20261011_084534_test','port':55441,'acceptance':'12 criteria closed and preserved by Tempo; current source fingerprint equals accepted QA candidate.'}
cp={**common,'passed':True,'database':b['restore_target']['database'],'port':55441,'dump_sha256':backup['sha256'],'empty_rollback_verified':True,'empty_rollback_evidence_date':compat['rechecked_at'],'empty_rollback_evidence_target':compat['target'],'fresh_destination_restoration':str(refs[1].relative_to(root)),'fresh_rollback_retest':False}
path={**common,'database':'desk_restore_20261009_174726_test','port':55441,'api_persistence_passed':True,'integrated_ui_ab_passed':True,'historical_ui_pass_source':'investor-ab-chromium-20261010.json','older_false_ui_status_preserved_in_original_files':True}
for name,value in [('backup-proof.json',backup),('guidance-qa-evidence.json',qa),('activation-compatibility.json',cp),('investor-path-qa-evidence.json',path)]:write(dest/name,value)
receipt={'at':now,'result':'existing accepted evidence reconciled; no tests repeated','code_hash':fingerprint,'evidence':chain,'proofs':[{'file':p.name,'sha256':sha(p)} for p in [dest/n for n in ['backup-proof.json','guidance-qa-evidence.json','activation-compatibility.json','investor-path-qa-evidence.json']]],'originals_preserved':True,'installer_gates_changed':False}
write(out/'B-activation-readiness-reconciliation-20261015.json',receipt)
print(json.dumps({'result':receipt['result'],'proofs':len(receipt['proofs']),'code_hash':fingerprint}))
@@ -0,0 +1,45 @@
{
"at": "2026-10-15T13:06:20+00:00",
"candidate": "B-final-fabf722bc8c6",
"restore_target": {
"database": "b_final_restore_20261015_124723_test",
"port": 55441
},
"DB_read_only": true,
"application_base_is_private_clone": true,
"candidate_source_and_bundle_from_restored_files": true,
"shared_vendor_dependency": "C:\\laragon\\www\\portal-investidor\/storage\/app\/private\/investmoz-v2\/portal-audit\/portal-stability-source-20261011_083742\/vendor",
"kernel_bootstrap": "passed",
"HTTP_kernel_routes": [
{
"method": "GET",
"path": "\/up",
"status": 200,
"body_bytes": 1757,
"body_sha256": "0e5f4ba27dfb22f477127fb7e6a45085f7f3e8cce5b541f99f785cd00751aaf0"
},
{
"method": "GET",
"path": "\/login",
"status": 200,
"body_bytes": 7743,
"body_sha256": "0ef3e76f37e9911f0204fb0ddfd8a690c886d66d6f74cf7d4bb3e00159e738e4"
},
{
"method": "GET",
"path": "\/oportunidades",
"status": 200,
"body_bytes": 209717,
"body_sha256": "91793ed7b3f195cb9db576feb9bb5c229060a0e2111110c364b60ed5f5c04185"
}
],
"model_read_in_restored_database": true,
"view_rendering_and_Vite_manifest": "passed",
"SSRandExternalConnectorsDisabled": true,
"session_and_cache": "array in clone only",
"database_changes": 0,
"active_changes": 0,
"functional_12_criteria_repeated": false,
"real_web_server_TLS_worker_boot_test": false,
"activation_authorized": false
}
@@ -0,0 +1,24 @@
{
"at": "2026-10-15T15:01:30.820936+00:00",
"candidate_original_SHA256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"candidate_unchanged": true,
"supplement_ZIP": "investmoz-B-suplemento-C137-sequencia-final-20261015.zip",
"supplement_ZIP_SHA256": "182fb269536aa7bd84b8694ec54d1b39bf5b072abe91d0f4b1284389755fc620",
"manifest_SHA256": "8e09e7c797a64ed2e233a41dcea80e86dd2dc949d512e1f20afc52930fee52f3",
"CRC_and_all_manifest_hashes_verified": true,
"C137_room_source_coherent_with_existing_bundle": true,
"source_count_base_plus_supplement": 36,
"documents": {
"PROPOSTA-UNICA-TEMPO.md": "15036b731859087ebb30e76ba507d5083d89e5dae0f494fc8b243edfc0e1fad2",
"PROCEDIMENTO-EXATO.md": "cc230d8f2da533fb93acb7fedc0d0ff35a18425b7b38f46bf53793eacfde9172",
"MAPA-DISPONIBILIZACAO-REVERSAO.json": "2c44996d7bcb086e4a7e4b0069372bd8a03620c3c04ed09e7b5f952ffc55e153",
"COMPATIBILIDADE-ESTADO-INTERMEDIO.json": "942b29203d9c095b0bfc280db773d86ff3db18ae9d8054b51f57cd79390180a9"
},
"maintenance_order_corrected": true,
"installer_only_after_artisan_up": true,
"twelve_criteria_closed_and_not_repeated": true,
"fresh_destination_backup": "near execution; not performed now",
"C137_inclusion_and_visual_limitation": "included in final authorization proposal, not activation consent already received",
"activation_authorized": false,
"active_changes": 0
}
@@ -0,0 +1,33 @@
{
"date": "2026-10-15",
"method": "Reutilização de provas existentes e verificação do código por leitura; sem novo ensaio funcional",
"existing_proofs": {
"option-B8-context-compatibility.json": "08dd85bcf8eea1c20f86d18f8b0c6480348670ce309b8afa70cf6e5f5596799e",
"option-B7-active-path-read.json": "cdf87d5b17b696aa3106d66bbed3f9c2854ae01ff4f2a459bd71dd0ed4c74f32",
"B-destination-preflight-readonly-20261015.json": "7674a0084f8c18a6ef18d21a89ca6d539523c5d7ab0c09e15a5511e6dd3524f2",
"B-restored-clone-boot-20261015.json": "7744a5e941bef358e9b027fae036a8f2bd708d2e34c017add73d119291119ca9"
},
"disabled_path_previous_technical_proof": {
"existing_bound_tool_payload_accepted": true,
"new_context_rejected": true,
"phases_and_steps_preserved": true
},
"source_reading": {
"InvestorPath.available": "enabled false short-circuits before schema-dependent logic",
"InvestorPath.contexts": "returns [] before join on path_definition_id when unavailable",
"LandAssistanceController.create": "enabled false rejects new context before query referencing path_definition_id",
"HandleInertiaRequests.share": "investorPathEnabled derived from available; does not require enabling for login/general shell",
"routes.virtual_desk": "GET/POST /management/balcao-install under auth,verified,PrivateInvestmentResponse and can:manage-portal; not VirtualDeskInstalled",
"maintenance": "artisan up must occur before authenticated installer; no maintenance bypass presumed"
},
"code_sha256": {
"app/Services/InvestorPath.php": "7734420bfe2fcee0e49a3ca759987d54877844afb68bbba0f2a6ec3d1ec33269",
"app/Http/Controllers/LandAssistanceController.php": "3177919b63517064d36f977b7f779bd4d7061329c98c8b3710978c179a420031",
"app/Http/Middleware/HandleInertiaRequests.php": "e117d366ce411944fd560b5b8117853859532e255bff5e732f1874a1eac70979",
"routes/virtual-desk.php": "cff6864e0b261ea086b50261c65fd056d6ddcd8fa9d71d6ad1bb07a738136cd2"
},
"evidence_limit": "Disabled-path compatibility proof ran in QA with schema already installed; missing-column safety and installer independence confirmed by short-circuit/route inspection, not claimed as newly executed HTTP on missing-schema state. Restored boot proof covers kernel/login/catalogue, not a new authenticated installer trial.",
"conclusion": "Intermediate code/build deployed + path disabled + application out of maintenance is the documented prerequisite for authenticated 190000 installation; enable only after installation verified.",
"twelve_criteria_repeated": false,
"active_changes": 0
}
@@ -0,0 +1,82 @@
{
"at": "2026-10-15T15:01:30.703302+00:00",
"candidate_base": "B-final-fabf722bc8c6",
"candidate_base_ZIP_SHA256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"candidate_unchanged": true,
"supplement_source": {
"path": "resources/js/pages/partnerships/room.tsx",
"sha256": "fea8a156ee7ff8b24492ec0bfe5e61ab4d6ecefe588f65bec67909fc704df53a",
"coherent_existing_compiled_file": "assets/room-LM3pUYAr.js",
"compiled_SHA256": "5130e9b6f98698568d847588656815fd3a3a6aa38cbdaf0bcd822d96c539c0be"
},
"source_count_base_plus_supplement": 36,
"new_functionality": false,
"new_build": false,
"C137_visual_limitation": "to be expressly accepted in final Tempo authorization; not claimed as observed",
"sequence": [
"fresh destination backup",
"path disabled",
"maintenance",
"source/build switch",
"operational checks",
"exit maintenance",
"authenticated absent-only190000 installation",
"verify installation",
"enable path flag",
"final operational checks"
],
"functional_tests_repeated": false,
"activation_authorized": false,
"files": [
{
"file": "COMPATIBILIDADE-ESTADO-INTERMEDIO.json",
"bytes": 2650,
"sha256": "942b29203d9c095b0bfc280db773d86ff3db18ae9d8054b51f57cd79390180a9"
},
{
"file": "fonte-QA/resources/js/pages/partnerships/room.tsx",
"bytes": 24165,
"sha256": "fea8a156ee7ff8b24492ec0bfe5e61ab4d6ecefe588f65bec67909fc704df53a"
},
{
"file": "MAPA-DISPONIBILIZACAO-REVERSAO.json",
"bytes": 53020,
"sha256": "2c44996d7bcb086e4a7e4b0069372bd8a03620c3c04ed09e7b5f952ffc55e153"
},
{
"file": "PROCEDIMENTO-EXATO.md",
"bytes": 8397,
"sha256": "cc230d8f2da533fb93acb7fedc0d0ff35a18425b7b38f46bf53793eacfde9172"
},
{
"file": "PROPOSTA-UNICA-TEMPO.md",
"bytes": 4890,
"sha256": "15036b731859087ebb30e76ba507d5083d89e5dae0f494fc8b243edfc0e1fad2"
},
{
"file": "provas-existentes/C137-build-QA.json",
"bytes": 786,
"sha256": "0463e05081af50e4e11c9dea3f72fa0a84553245d27184996a45f4359d445a09"
},
{
"file": "provas-existentes/C137-QA-delta.json",
"bytes": 1068,
"sha256": "ec648d2ffda06681f88510007615cb7ce92f968af7b429b11107a470b3bf8f0e"
},
{
"file": "provas-existentes/option-B7-active-path-read.json",
"bytes": 821,
"sha256": "cdf87d5b17b696aa3106d66bbed3f9c2854ae01ff4f2a459bd71dd0ed4c74f32"
},
{
"file": "provas-existentes/option-B8-context-compatibility.json",
"bytes": 423,
"sha256": "08dd85bcf8eea1c20f86d18f8b0c6480348670ce309b8afa70cf6e5f5596799e"
},
{
"file": "provas-existentes/partnership-revocation-closed-room-revocation-HTTP.json",
"bytes": 5454,
"sha256": "ad485d3ece8350925962ff380ef1498ad365d2610bdcd7b1ddfe29d03a8d3439"
}
]
}
@@ -0,0 +1,36 @@
# Procedimento exato — opção B com suplemento C137
**Preparado para a autorização única proposta; não executado.** Destino: C:/laragon/www/portal-investidor, https://portal-investidor.test, investemoz:5432. Candidata base B-final-fabf722bc8c6 preservada; acrescentar somente room.tsx do suplemento, total36 fontes. Usar MAPA-DISPONIBILIZACAO-REVERSAO.json e hashes do manifesto. Os inventários de15/10 são referências: devem coincidir na janela ou ser reconciliados por leitura antes de escrever.
## Sequência da futura janela autorizada
1. **Autorização e integridade.** Obter a decisão expressa da Tempo nos quatro pontos da proposta, incluindo a ressalva visual C137. Verificar ZIP original, suplemento, manifestos, hashes before das36 fontes,769 recursos atuais, configurações e locks. Confirmar destino real investemoz:5432. Divergência interrompe a troca até reconciliar o mapa; nunca usar dados/contas QA no ativo.
2. **Backup próximo da execução.** Preparar então o snapshot consistente do destino, originais, configuração/cifra e ACLs; restaurar em novo clone55441*_test e verificar. Conservar fonte/build/configuração anteriores para reversão. O backup QA e a cópia de código inventariada não substituem esse backup fresco. Não antecipado nesta preparação.
3. **Percurso desabilitado.** Confirmar a configuração efetiva `INVESTOR_PATH_ENABLED=false` antes da troca; o destino lido já o mantinha desabilitado. Se houver divergência, parar para a decisão da janela, sem presumir configuração. Manter COUNTRY02/workflow/perfis e DevToolsOFF. Não habilitar o percurso por instalar colunas.
4. **Manutenção e troca.** Com PHP C:/laragon/bin/php/php-8.5.11-Win32-vs17-x64/php.exe na raiz do destino, executar `artisan down --retry=60`. Não abrir o instalador nesta fase. Montar build base incluído no ZIP original e sobrepor build da candidata, conservando CSS/fontes e recursos antigos. Disponibilizar apenas36 fontes do mapa —35 originais mais room.tsx. Verificar before/after, preservando ACLs. Recursos de nome com hash já existente devem ter bytes iguais; colisão divergente interrompe. Selecionar public/build/manifest.json por último, com fonts-manifest e dependências já presentes. Não extrair o código histórico sobre o destino, não apagar recursos antigos nem executar build/instalação de dependências.
5. **Conferência técnica ainda em manutenção.** Conferir hashes de fonte/build e referências Vite/fontes; confirmar flagfalse, DevToolsOFF e ausência de mudança nas dependências/serviços. `artisan view:clear` só para views compiladas. Se for indispensável renovar OPcache, usar o mecanismo administrativo existente/reload gracioso do Apache ativo definido no inventário, dentro da janela autorizada, sem endpoint novo ou alteração de php.ini. Não tocar em instânciasQA, filas ou ClamD. Não presumir exceção de manutenção.
6. **Sair de manutenção antes do instalador.** Executar `artisan up`. Conferir apenas arranque/PHPweb/HTTPS/login/ativos, mantendo o percurso desabilitado. Se este estado falhar, entrar novamente em manutenção e reverter código/build; não tentar contornar a manutenção com segredo/bypass. A montagem já tem guards de percurso indisponível e instalador independente, descritos em COMPATIBILIDADE-ESTADO-INTERMEDIO.json.
7. **Instalação autenticada somente190000.** Agora, com aplicação fora de manutenção, fazer login/MFA com conta real já autorizada a manage-portal. Abrir GET /management/balcao-install; conferir identidade do destino, preview/hash e pendência exata2026_10_09_190000_prepare_investor_path. Se já estiver instalada e colunas/definição corresponderem, não repetir. Se ausente, submeter o POST do próprio formulário com CSRF/hash e os controlos existentes de backup/QA/compatibilidade. O serviço transacional aplica somente migrações ausentes e regista auditoria. Não usar SQL direto, configuração de bypass nem migrate genérico. Se aparecer outra pendência ou estado parcial, parar; não alargar o lote.
8. **Verificar antes de habilitar.** Confirmar o registo exato da migração, as duas colunas opcionais/FK, a definição imutável e o resultado auditado. Definição preexistente deve coincidir; nenhuma conversão de dossiers. Se um gate existente não reconhecer as provas para o código final, reconciliar a proveniência e recibos pelos controlos existentes, sem fabricar readiness, ignorar validações ou repetir os12 critérios por conveniência.
9. **Habilitar percurso.** Só depois da instalação verificada, alterar de forma controlada apenas INVESTOR_PATH_ENABLED para true, como autorizado na mesma decisão. Registar before/after e hash da configuração; não copiar o .envQA nem repor todo o .env. A configuração do destino estava sem cache; se o estado tiver mudado, tratar explicitamente o cache efetivo na janela. Preservar todas as restantes flags e DevToolsOFF.
10. **Conferência final operacional.** Verificar configuração efetiva, hashes, PHPweb/HTTPS, arranque e carregamento de bundle/fontes, disponibilidade operacional e ausência de erro500/ativo404. Registar recibo do destino, janela e autor. Não refazer os12 percursos, não reabrir anúncios nem recriar pedidos. Se ocorrer regressão, conter a ação e reverter conforme abaixo.
## Efeitos da instalação prevista
190000 acrescenta investor_journeys.path_definition_id UUID NULL com FK questionnaire_versions(id)/ON DELETE RESTRICT e journey_steps.path_detail TEXT NULL. Insere definição investor-path-19/versão1/pt-MZ/ID61000919-0000-4000-8000-000000000001 publicada com início09/10/2026 somente quando ausente; exige correspondência se já existir. Regista a migração. Não converte dossiers, não renumera etapas e não liga navegação automaticamente.
## Compatibilidade do estado intermédio
Prova técnica existente option-B8-context-compatibility.json: percursofalse aceita payload de ferramenta com vínculo já guardado, recusa novo contexto e preserva fases/etapas. Prova de leitura do destino option-B7-active-path-read.json e inventário operacional: flagfalse e190000 ausente. Leitura atual da fonte: InvestorPath.available retornafalse por curto-circuito antes das consultas dependentes; contexts retorna[] antes do join; novo contexto Terra é recusado antes da consulta à coluna; HandleInertiaRequests deriva a navegação de available. GET/POST /management/balcao-install estão sob auth/verified/PrivateInvestmentResponse/can:manage-portal, fora de VirtualDeskInstalled.
Esta combinação confirma por prova anterior e inspeção a ordem com percurso desabilitado e aplicação disponível para instalação. A prova dinâmica anterior tinha schema instalado; não se declara novo teste HTTP com schema ausente. Não se reabrem os12 critérios nem se inventa exceção à manutenção.
## Reversão correspondente
Se falhar a troca antes de instalar, entrar/manter manutenção, repor as36 fontes anteriores e manifestos/build coerentes do backup fresco pelos hashes before; manter os recursos antigos. Um caminho originalmente ausente só pode ser removido se ainda tiver hash idêntico ao entregue. Limpar apenas views compiladas e sair de manutenção após verificar o arranque; preservar percursofalse.
Se190000 já tiver sido aplicado, uma reversão de código não deve eliminar colunas ou definição, nem executar down de migração usada. Se a flag já tiver sido habilitada, desabilitar apenas essa flag conforme o plano autorizado; conservar histórico e dados. Restauro integral da base exige decisão adicional e reconciliação das alterações posteriores ao backup. Nunca usar dumpQA no ativo.
ParaC137, repor room.tsx anterior junto com build/manifestos coerentes anteriores à janela. A interface poderá voltar a ocultar a retirada em sala encerrada, mas nenhuma partilha retirada deve ser recriada, nenhum documento eliminado e nenhuma permissão de servidor ampliada ou restaurada. Não substituir apenas um chunk de compilação incompatível. O mapa do suplemento identifica fonte/hashes e os recursos de build da candidata base, que permanece imutável.
Não executar novamente030000/040000/050000, instalar dependências, importar fixtures, limpar sessões/filas, alterar TLS/CA ou ativar funcionalidades distintas desta decisão.
@@ -0,0 +1,33 @@
# Proposta única de autorização final à Tempo
**Proposta para decisão; nenhuma ativação autorizada ou executada por esta mensagem.** Manter a candidata `B-final-fabf722bc8c6` e os 12 critérios aceites. O ZIP original, SHA256 `c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78`, fica imutável. O suplemento acrescenta a fonte C137 coerente com a compilação já preparada, sem novo build ou funcionalidade.
## Texto da autorização proposta
«A Tempo autoriza, numa única janela, a entrega da opção B com o suplemento C137; a instalação somente de `2026_10_09_190000_prepare_investor_path`, se continuar ausente, pela ação autenticada existente; a habilitação de `INVESTOR_PATH_ENABLED` apenas após verificar essa instalação; e a preparação, próximo da execução, do backup/restauro fresco do destino e da reversão correspondente. A Tempo inclui expressamente C137 e aceita a sua limitação visual identificada abaixo. A candidata base e os 12 critérios aceites mantêm-se preservados, sem repetição dos percursos.»
Este texto é a decisão submetida à Tempo, não um registo de consentimento já recebido.
## 190000 é uma dependência já prevista
No destino inventariado, apenas esta migração do instalador permanece ausente. Acrescenta `investor_journeys.path_definition_id UUID NULL`, referência a `questionnaire_versions(id)` com `ON DELETE RESTRICT`, e `journey_steps.path_detail TEXT NULL`. Regista a migração e insere somente se ausente a definição imutável `investor-path-19`, versão1/pt-MZ, ID `61000919-0000-4000-8000-000000000001`, publicada com início09/10/2026. Definição já existente deve corresponder, ou a ação é recusada. Não converte dossiers nem renumera etapas.
Usar `GET/POST /management/balcao-install`, conta real já habilitada a `manage-portal`, MFA/CSRF e hash da pré-visualização. Aplicar apenas a pendência exata; não reinstalar030000/040000/050000, não usar migração genérica nem SQL de contorno. A instalação não liga automaticamente o percurso.
## C137 incluído no suplemento para decisão expressa
A interface anterior escondia a retirada de partilha numa sala encerrada/cancelada, apesar de o servidor já a permitir ao autor. A correção mostra esse controlo quando o documento do autor permanece partilhado e explica o estado; novas partilhas continuam recusadas, sem ampliar permissões.
- Fonte acrescentada: `resources/js/pages/partnerships/room.tsx`, SHA256 `fea8a156ee7ff8b24492ec0bfe5e61ab4d6ecefe588f65bec67909fc704df53a`. Destino anterior: `43b64ce253bf450888fcd3b10d5e5860cc2633aed29a82cde965d82ae99172e3`. O mapa passa de35 para36 fontes considerando o suplemento.
- Bundle existente e verificado: `public/build/assets/room-LM3pUYAr.js`. A alteração já constava do bundle base; a fonte acrescentada elimina a divergência fonte/compilação. Não é necessário recompor o bundle.
- Provas anteriores: `C137-QA-delta.json`, `C137-build-QA.json` e `partnership-revocation-closed-room-revocation-HTTP.json`. TypeScript/build passaram. API: autor revoga após cancelamento, destinatário nas sessões anterior/nova404, original do autor200/hash igual, revogação idempotente, nova partilha409, não autor/não participante403 e anónimo401; sala anterior preservada.
- **Limitação a aceitar expressamente:** a prova visual específica de C137 não está demonstrada nas provas existentes. Não se atribui a C137 a aceitação dos12 critérios B e não se solicita nova auditoria.
- Reversão: repor `room.tsx` e a compilação/manifestos coerentes anteriores à janela; preservar recursos anteriores, originais e revogações já registadas. Não recriar partilhas nem alterar permissões do servidor.
## Ordem operacional corrigida
Backup/restauro fresco do destino → percurso desabilitado → manutenção → troca das36 fontes e recursos, manifesto por último → conferência técnica em manutenção → saída de manutenção → login/MFA e instalação autenticada somente190000 → verificar colunas/definição/registo → habilitar `INVESTOR_PATH_ENABLED` → conferência operacional final. O instalador nunca é pedido enquanto a manutenção estiver ativa. Não é presumida exceção ou bypass.
O estado intermédio é sustentado pelas provas existentes de compatibilidade com percurso desabilitado e pela leitura dos guards/rotas. A prova anterior usou schema QA já instalado; a segurança face às colunas ausentes foi confirmada por leitura do curto-circuito, sem alegar novo ensaio HTTP desse estado. O instalador é independente da disponibilidade do percurso. Os12 critérios não foram repetidos.
Backup/restauro fresco do destino apenas próximo da execução. A recuperação operacional no clone está encerrada. Sem alteração do ativo, de flags ou instalação nesta preparação.
@@ -0,0 +1,24 @@
{
"at": "2026-10-15T15:01:30.820936+00:00",
"candidate_original_SHA256": "c6f26f9b0f42a0603311e9a8acae35b9dc6aa14a1f5269f42a296279a8026c78",
"candidate_unchanged": true,
"supplement_ZIP": "investmoz-B-suplemento-C137-sequencia-final-20261015.zip",
"supplement_ZIP_SHA256": "182fb269536aa7bd84b8694ec54d1b39bf5b072abe91d0f4b1284389755fc620",
"manifest_SHA256": "8e09e7c797a64ed2e233a41dcea80e86dd2dc949d512e1f20afc52930fee52f3",
"CRC_and_all_manifest_hashes_verified": true,
"C137_room_source_coherent_with_existing_bundle": true,
"source_count_base_plus_supplement": 36,
"documents": {
"PROPOSTA-UNICA-TEMPO.md": "15036b731859087ebb30e76ba507d5083d89e5dae0f494fc8b243edfc0e1fad2",
"PROCEDIMENTO-EXATO.md": "cc230d8f2da533fb93acb7fedc0d0ff35a18425b7b38f46bf53793eacfde9172",
"MAPA-DISPONIBILIZACAO-REVERSAO.json": "2c44996d7bcb086e4a7e4b0069372bd8a03620c3c04ed09e7b5f952ffc55e153",
"COMPATIBILIDADE-ESTADO-INTERMEDIO.json": "942b29203d9c095b0bfc280db773d86ff3db18ae9d8054b51f57cd79390180a9"
},
"maintenance_order_corrected": true,
"installer_only_after_artisan_up": true,
"twelve_criteria_closed_and_not_repeated": true,
"fresh_destination_backup": "near execution; not performed now",
"C137_inclusion_and_visual_limitation": "included in final authorization proposal, not activation consent already received",
"activation_authorized": false,
"active_changes": 0
}
@@ -0,0 +1,524 @@
import { createOperationKey } from '@/lib/operation-key';
import { useForm, usePage, Link, router } from '@inertiajs/react';
import {
Frame,
Field,
Errors,
control,
button,
labels,
type Partnership,
} from './shared';
type Room = {
id: number;
status: string;
version: number;
agreement: {
title: string;
terms: string;
confirmations: Record<string, { actor_id: number; date: string }>;
legal_signature_status: string;
} | null;
};
type Milestone = {
id: number;
title: string;
responsible_id: number;
due_date: string | null;
status: string;
evidence: string | null;
version: number;
};
type Props = {
room: Room;
partnership: Partnership & { user_id: number };
interest: { id: number; user_id: number };
canWrite: boolean;
messages: {
id: number;
name: string;
author_id: number;
body: string;
created_at: string;
}[];
documents: {
id: number;
owner_id: number;
file_name: string;
shared: boolean;
status: string;
malware_scan_status: string;
}[];
milestones: Milestone[];
};
function MilestoneForm({ p, item }: { p: Props; item?: Milestone }) {
const form = useForm({
title: item?.title ?? '',
responsible_id: item?.responsible_id ?? p.partnership.user_id,
due_date: item?.due_date ?? '',
status: item?.status ?? 'pending',
evidence: item?.evidence ?? '',
version: item?.version ?? null,
});
return (
<form
className="space-y-3 rounded border p-4"
onSubmit={(e) => {
e.preventDefault();
if (item)
form.put(
`/parcerias/salas/${p.room.id}/marcos/${item.id}`,
{ preserveScroll: true },
);
else
form.post(`/parcerias/salas/${p.room.id}/marcos`, {
preserveScroll: true,
});
}}
>
<h3 className="font-bold">
{item ? 'Atualizar marco' : 'Acrescentar marco'}
</h3>
<Field label="Entregável">
<input
className={control}
value={form.data.title}
onChange={(e) => form.setData('title', e.target.value)}
/>
</Field>
<Field label="Responsável">
<select
className={control}
value={form.data.responsible_id}
onChange={(e) =>
form.setData('responsible_id', Number(e.target.value))
}
>
<option value={p.partnership.user_id}>Proponente</option>
<option value={p.interest.user_id}>Candidato</option>
</select>
</Field>
<Field label="Data prevista">
<input
className={control}
type="date"
value={form.data.due_date}
onChange={(e) => form.setData('due_date', e.target.value)}
/>
</Field>
<Field label="Estado">
<select
className={control}
value={form.data.status}
onChange={(e) => form.setData('status', e.target.value)}
>
{['pending', 'progress', 'completed'].map((x) => (
<option key={x} value={x}>
{x === 'pending' ? 'Pendente' : labels[x]}
</option>
))}
</select>
</Field>
<Field label="Evidência ou referência do resultado">
<textarea
className={control}
value={form.data.evidence}
onChange={(e) => form.setData('evidence', e.target.value)}
/>
</Field>
<Errors errors={form.errors} />
<button className={button} disabled={form.processing}>
Guardar marco
</button>
</form>
);
}
export default function Page(p: Props) {
return <RoomPage key={p.room.id + ':' + p.room.version} {...p} />;
}
function RoomPage(p: Props) {
const { auth } = usePage<{ auth: { user: { id: number } } }>().props;
const message = useForm({ body: '', client_key: createOperationKey() });
const agreement = useForm({
version: p.room.version,
action: 'record',
title: p.room.agreement?.title ?? '',
terms: p.room.agreement?.terms ?? '',
reason: '',
});
const upload = useForm<{ file: File | null; shared: boolean }>({
file: null,
shared: false,
});
const act = (action: string) => {
agreement.transform((data) => ({ ...data, action }));
agreement.post(`/parcerias/salas/${p.room.id}/acordo`, {
preserveScroll: true,
});
};
const mutable =
p.canWrite && !['closed', 'cancelled'].includes(p.room.status);
return (
<Frame title={'Conexão privada — ' + p.partnership.title}>
<div className="space-y-6">
<Link
className="underline"
href={'/parcerias/' + p.partnership.id}
>
Regressar à parceria
</Link>
<p>
Estado da conexão: {labels[p.room.status]}. Esta sala
pertence apenas às partes autorizadas; não encerra outras
candidaturas.
</p>
<section className="space-y-4 rounded border p-5">
<h2 className="text-xl font-bold">
Mensagens e esclarecimentos
</h2>
{p.messages.map((m) => (
<article className="bg-muted rounded p-4" key={m.id}>
<p className="font-semibold">
{m.name} · {m.created_at}
</p>
<p className="whitespace-pre-wrap">{m.body}</p>
</article>
))}
{mutable && (
<form
className="space-y-3"
onSubmit={(e) => {
e.preventDefault();
message.post(
`/parcerias/salas/${p.room.id}/mensagens`,
{
preserveScroll: true,
onSuccess: () => {
message.setData({
body: '',
client_key: createOperationKey(),
});
},
},
);
}}
>
<Field label="Mensagem privada">
<textarea
className={control}
disabled={message.processing}
value={message.data.body}
onChange={(e) =>
message.setData('body', e.target.value)
}
/>
</Field>
<Errors errors={message.errors} />
<button
className={button}
disabled={message.processing}
>
Enviar mensagem
</button>
</form>
)}
</section>
<section className="space-y-4 rounded border p-5">
<h2 className="text-xl font-bold">
Documentos autorizados
</h2>
<p>
O original fica no repositório privado. A partilha exige
autorização explícita; o download exige análise
antimalware limpa e hash correspondente. Anexar não
confirma autenticidade nem vigência.
</p>
<p
role="status"
aria-live="polite"
aria-label="Documentos disponíveis nesta sala"
>
{p.documents.length
? `${p.documents.length} documento(s) disponível(is) para esta conta.`
: 'Nenhum documento está autorizado para consulta por esta conta nesta sala.'}
</p>
{!mutable && p.documents.some((d) => d.shared && d.owner_id === auth.user.id) && (
<p role="status" aria-live="polite">
A sala está encerrada. O autor pode retirar uma autorização de partilha existente; novas partilhas permanecem indisponíveis.
</p>
)}
{p.documents.map((d) => (
<article key={d.id}>
<p>
{d.file_name} ·{' '}
{d.shared
? 'Partilhado com a contraparte'
: 'Privado do autor'}{' '}
· Análise: {d.malware_scan_status}
</p>
{d.owner_id === auth.user.id && (mutable || d.shared) && (
<button
className="underline"
onClick={() =>
router.post(
`/parcerias/salas/${p.room.id}/documentos/${d.id}/partilha`,
{ shared: !d.shared },
{ preserveScroll: true },
)
}
>
{d.shared
? 'Retirar autorização de partilha'
: 'Autorizar partilha com a contraparte'}
</button>
)}
{d.status === 'active' &&
d.malware_scan_status === 'clean' && (
<a
className="underline"
href={`/parcerias/salas/${p.room.id}/documentos/${d.id}`}
>
Descarregar documento
</a>
)}
</article>
))}
{mutable && (
<form
className="space-y-3"
onSubmit={(e) => {
e.preventDefault();
upload.post(
`/parcerias/salas/${p.room.id}/documentos`,
{
forceFormData: true,
preserveScroll: true,
},
);
}}
>
<Field label="Anexar PDF ou imagem">
<input
type="file"
className="w-full max-w-full min-w-0"
accept=".pdf,.jpg,.jpeg,.png"
onChange={(e) =>
upload.setData(
'file',
e.target.files?.[0] ?? null,
)
}
/>
</Field>
<label className="block">
<input
type="checkbox"
checked={upload.data.shared}
onChange={(e) =>
upload.setData(
'shared',
e.target.checked,
)
}
/>{' '}
Autorizo a consulta pela contraparte desta sala.
</label>
<Errors errors={upload.errors} />
<button
className={button}
disabled={
upload.processing || !upload.data.file
}
>
Guardar documento privado
</button>
</form>
)}
</section>
<section className="space-y-4 rounded border p-5">
<h2 className="text-xl font-bold">
Acordo e plano conjunto
</h2>
<p>
Registe o instrumento, objetivos, contribuições,
responsabilidades, indicadores, riscos, dependências e
condições de saída. A confirmação no portal regista a
concordância comunicada pelas partes; não certifica
assinatura jurídica ou due diligence.
</p>
{p.room.agreement && (
<>
<h3 className="font-bold">
{p.room.agreement.title}
</h3>
<p className="whitespace-pre-wrap">
{p.room.agreement.terms}
</p>
<p>
Confirmações:{' '}
{Object.entries(p.room.agreement.confirmations)
.map(
([party, c]) =>
`${party}: autor ${c.actor_id}, ${c.date}`,
)
.join('; ') || 'Pendentes'}
</p>
</>
)}
{mutable && (
<>
<Field label="Motivo da ação">
<textarea
className={control}
value={agreement.data.reason}
onChange={(e) =>
agreement.setData(
'reason',
e.target.value,
)
}
/>
</Field>
{['negotiation', 'agreement_recorded'].includes(
p.room.status,
) && (
<>
<Field label="Título do instrumento">
<input
className={control}
value={agreement.data.title}
onChange={(e) =>
agreement.setData(
'title',
e.target.value,
)
}
/>
</Field>
<Field label="Condições e plano de valor">
<textarea
className={control}
rows={6}
value={agreement.data.terms}
onChange={(e) =>
agreement.setData(
'terms',
e.target.value,
)
}
/>
</Field>
<button
className={button}
disabled={
agreement.processing ||
!agreement.data.reason
}
onClick={() => act('record')}
>
Registar versão do acordo
</button>
</>
)}
<div className="flex flex-wrap gap-3">
{p.room.status === 'agreement_recorded' && (
<button
className={button}
disabled={
agreement.processing ||
!agreement.data.reason
}
onClick={() => act('confirm')}
>
Confirmar pela minha parte
</button>
)}
{p.room.status === 'agreed' && (
<button
className={button}
disabled={
agreement.processing ||
!agreement.data.reason
}
onClick={() => act('start')}
>
Iniciar acompanhamento
</button>
)}
{p.room.status === 'execution' && (
<button
className={button}
disabled={
agreement.processing ||
!agreement.data.reason
}
onClick={() => act('complete')}
>
Concluir após os marcos
</button>
)}
{['agreed', 'execution'].includes(
p.room.status,
) && (
<button
className={button}
disabled={
agreement.processing ||
!agreement.data.reason
}
onClick={() => act('renew')}
>
Registar renovação
</button>
)}
<button
className={button}
disabled={
agreement.processing ||
!agreement.data.reason
}
onClick={() => act('cancel')}
>
Cancelar conexão com motivo
</button>
</div>
<Errors errors={agreement.errors} />
</>
)}
</section>
<section className="space-y-4">
<h2 className="text-xl font-bold">Marcos e responsáveis</h2>
<p>
Participação atual:{' '}
{auth.user.id === p.partnership.user_id
? 'Proponente'
: auth.user.id === p.interest.user_id
? 'Candidato'
: 'Representante autorizado'}
.
</p>
{p.milestones.map((m) => (
<article
key={m.id + ':' + m.version}
className="space-y-3"
>
<p>
{m.title} ·{' '}
{m.status === 'pending'
? 'Pendente'
: labels[m.status]}{' '}
· Prazo: {m.due_date ?? 'Pendente'} ·
Responsável ID {m.responsible_id}
</p>
{mutable && <MilestoneForm p={p} item={m} />}
</article>
))}
{mutable &&
['agreement_recorded', 'agreed', 'execution'].includes(
p.room.status,
) && <MilestoneForm p={p} />}
</section>
</div>
</Frame>
);
}
@@ -0,0 +1,20 @@
{
"case": "C137",
"at": "2026-10-12T21:27:25.485165+00:00",
"target": {
"database": "stability_consumers_20261011_084534_test",
"port": 55441
},
"file": "resources/js/pages/partnerships/room.tsx",
"before_sha256": "43b64ce253bf450888fcd3b10d5e5860cc2633aed29a82cde965d82ae99172e3",
"QA_after_sha256": "fea8a156ee7ff8b24492ec0bfe5e61ab4d6ecefe588f65bec67909fc704df53a",
"active_sha256_unchanged": "43b64ce253bf450888fcd3b10d5e5860cc2633aed29a82cde965d82ae99172e3",
"root_cause": "The UI guarded revoke and grant with mutable; closed/cancelled rooms hid revocation allowed by server.",
"scope": "Author may revoke existing shared document in closed room; cannot grant new share there. No server permission changed.",
"API_variant_proof": "partnership-revocation-closed-room-revocation-HTTP.json",
"visual_reproduction_and_acceptance": "pending C135",
"compiled": true,
"active_changes": 0,
"QA_manifest_SHA256": "87e77091835fe471b777e204d8c0487b70de3cc84a38942cc3796e4acb9a7067",
"served_asset_verified": true
}
@@ -0,0 +1,23 @@
{
"at": "2026-10-12T21:27:25.812269+00:00",
"QA_source": "C:\\laragon\\www\\portal-investidor\\storage\\app\\private\\investmoz-v2\\portal-audit\\portal-stability-source-20261011_083742",
"active_changes": 0,
"old_QA_manifest_SHA256": "cf78d5516251bc27c0d1b74fdfc257adf9a3113276dce9109c3c312e57d70fe9",
"backup_sha256": "4dccab29ca8902a52e03284cbbf9864d4e79e70d397c871051bea824b6839226",
"visual_observed": false,
"commands": [
{
"script": "types",
"exit": 0
},
{
"script": "build",
"exit": 0
}
],
"result": "passed",
"new_QA_manifest_SHA256": "87e77091835fe471b777e204d8c0487b70de3cc84a38942cc3796e4acb9a7067",
"prepared_assets": 159,
"old_assets_preserved": true,
"atomic_manifest_switch": true
}
@@ -0,0 +1,19 @@
{
"inspection_date": "2026-10-13",
"inspection_time_UTC": "approximately 14:20; not an exact recorded timestamp",
"target": {"database": "investemoz", "port": 5432},
"SQL_read_only": true,
"COUNTRY02_enabled": true,
"investor_path_enabled": false,
"exact_path_migration": "2026_10_09_190000_prepare_investor_path",
"exact_path_migration_installed": false,
"other_migrations_matching_190000": [
"2026_10_03_190000_allow_public_read_of_published_tax_parameters",
"2026_10_07_190000_create_internal_virtual_desk"
],
"path_columns": {"investor_journeys.path_definition_id": false, "journey_steps.path_detail": false},
"number_fragment_match_not_used_as_installation_proof": true,
"A_B_C37_scoped_closures_preserved": true,
"active_writes": 0,
"new_login_or_MFA_tests_in_active": false
}

Some files were not shown because too many files have changed in this diff Show More