diff --git a/app/Http/Controllers/InvestmentPortfolioController.php b/app/Http/Controllers/InvestmentPortfolioController.php
index 178b959f..3802d203 100644
--- a/app/Http/Controllers/InvestmentPortfolioController.php
+++ b/app/Http/Controllers/InvestmentPortfolioController.php
@@ -61,8 +61,15 @@ class InvestmentPortfolioController extends Controller
{
$management = $request->routeIs('management.portfolio*');
$filters = $request->validate(['q' => ['nullable', 'string', 'max:120'], 'kind' => ['nullable', 'in:corridor,cluster,project'],
+ 'sector' => ['nullable', 'string', 'max:500'],
'province_id' => ['nullable', 'uuid'], 'district_id' => ['nullable', 'uuid'], 'admin_post_id' => ['nullable', 'uuid'], 'locality_id' => ['nullable', 'uuid']]);
$query = $management ? InvestmentDossier::query() : self::visible();
+ $sectorOptions = ($management ? InvestmentDossier::query() : self::visible())
+ ->whereNotNull('content->sector')->get()->pluck('content.sector')
+ ->filter(fn ($sector) => is_string($sector) && trim($sector) !== '')->unique()->sort()->values();
+ if (! empty($filters['sector'])) {
+ $query->where('content->sector', $filters['sector']);
+ }
if (! empty($filters['kind'])) {
$query->whereNotNull($filters['kind'].'_id');
}
@@ -76,7 +83,7 @@ class InvestmentPortfolioController extends Controller
}
return Inertia::render('portfolio/index', ['records' => $query->orderBy('title')->paginate(30)->withQueryString(),
- 'management' => $management, 'filters' => $filters, 'territorySelection' => $territorySelection]);
+ 'management' => $management, 'filters' => $filters, 'sectors' => $sectorOptions, 'territorySelection' => $territorySelection]);
}
public function show(Request $request, string $id): Response
@@ -137,6 +144,13 @@ class InvestmentPortfolioController extends Controller
'origin' => $origin ? ['id' => $origin->id, 'title' => $origin->title] : null, 'opportunities' => $opportunities, 'chains' => $chains]);
}
+ public function resumeInterest(Request $request, string $id): RedirectResponse
+ {
+ self::visible()->findOrFail($id);
+ $data = $request->validate(['catalogue_query' => ['nullable', 'string', 'max:4000']]);
+ return redirect('/carteira/'.$id.'?'.http_build_query([...$data, 'prepare_interest' => '1']));
+ }
+
public function save(Request $request, InvestmentDossier $dossier): RedirectResponse
{
$data = $request->validate(['version_no' => ['required', 'integer', 'min:1'], 'title' => ['required', 'string', 'max:255'], 'source' => ['required', 'string', 'max:2000'],
diff --git a/app/Http/Controllers/InvestorContextController.php b/app/Http/Controllers/InvestorContextController.php
index 90b1bd30..982faffa 100644
--- a/app/Http/Controllers/InvestorContextController.php
+++ b/app/Http/Controllers/InvestorContextController.php
@@ -103,12 +103,17 @@ final class InvestorContextController extends Controller
if ($kept && ($kept['territory']['key'] ?? null) !== ($entry['territory']['key'] ?? null)) $differences[] = ['title'=>$entry['opportunity']['title'],'saved'=>$kept['territory']['title']??'Por definir','requested'=>$entry['territory']['title']??'Por definir'];
}
$complements = isset($draft['complements']) ? app(\App\Services\InvestmentComplements::class)->resolve($draft['complements'], $data['context']['complements'] ?? []) : ($data['context']['complements'] ?? []);
+ $entryTerritory = null;
+ if (($source['kind'] ?? null) === 'portfolio') {
+ $path = app(InvestmentGeography::class)->selection($r->validate(['province_id' => 'nullable|uuid', 'district_id' => 'nullable|uuid', 'admin_post_id' => 'nullable|uuid', 'locality_id' => 'nullable|uuid']));
+ if ($path) $entryTerritory = $context->reference('territory:'.$path[array_key_last($path)]->id);
+ }
foreach ($this->entryComplements($r) as $entry) {
$tag = 'complement:'.hash('sha256', $entry['key'].'@'.($selectionKey ?? ''));
$entrySources[] = $tag;
if (!in_array($tag, $draft['entry_sources'] ?? [], true)) $complements = collect([...$complements, $entry])->unique('key')->values()->all();
}
- return Inertia::render('investor-path/context', ['entryComplements' => $complements, 'entryLocationDifferences'=>$differences,'entrySources'=>$entrySources,'draft' => $draft, 'requestedChoices' => $choices, 'initial' => $data, 'options' => $context->options(), 'source' => $source, 'territorySelection' => isset($data['context']['selection']['territory']) ? app(InvestmentGeography::class)->path($data['context']['selection']['territory']['id']) : []]);
+ return Inertia::render('investor-path/context', ['entryTerritory' => $entryTerritory, 'entryComplements' => $complements, 'entryLocationDifferences'=>$differences,'entrySources'=>$entrySources,'draft' => $draft, 'requestedChoices' => $choices, 'initial' => $data, 'options' => $context->options(), 'source' => $source, 'territorySelection' => isset($data['context']['selection']['territory']) ? app(InvestmentGeography::class)->path($data['context']['selection']['territory']['id']) : ($entryTerritory ? app(InvestmentGeography::class)->path($entryTerritory['id']) : [])]);
}
public function preview(Request $r, string $id, InvestorContext $context)
@@ -125,9 +130,16 @@ final class InvestorContextController extends Controller
{
$d = $r->validate(['source' => 'nullable|string|max:100', 'step' => ['nullable', 'regex:/^S(0[1-9]|1[0-9])$/']]);
$ref = isset($d['source']) ? $context->reference($d['source']) : null;
+ $submissionId = $r->validate(['submission' => 'nullable|uuid'])['submission'] ?? null;
+ $entrySubmission = null;
+ if ($submissionId) {
+ $submission = \App\Models\InvestmentSubmission::where('id', $submissionId)->where('user_id', $r->user()->id)->where('status', 'draft')->firstOrFail();
+ abort_unless(($ref['kind'] ?? null) === 'portfolio' && $submission->dossier_id === $ref['id'], 422, 'Conserve a ficha de origem da manifestação.');
+ $entrySubmission = ['id' => $submission->id, 'version' => $submission->version];
+ }
$choices = $this->entryChoices($r, $context);
- return Inertia::render('investor-path/context-start', ['entryComplements' => $this->entryComplements($r), 'entryQuery' => $r->only(['complement_origin', 'complement_code', 'complement_target', 'complement_territory', 'from_dossier', 'province_id', 'district_id', 'admin_post_id', 'locality_id']), 'opportunityChoices' => $choices, 'contexts' => $path->contexts($r->user()), 'source' => $ref, 'step' => $d['step'] ?? null]);
+ return Inertia::render('investor-path/context-start', ['entrySubmission' => $entrySubmission, 'entryComplements' => $this->entryComplements($r), 'entryQuery' => $r->only(['complement_origin', 'complement_code', 'complement_target', 'complement_territory', 'from_dossier', 'province_id', 'district_id', 'admin_post_id', 'locality_id']), 'opportunityChoices' => $choices, 'contexts' => $path->contexts($r->user()), 'source' => $ref, 'step' => $d['step'] ?? null]);
}
public function installation(Request $r, InvestorContextInstallation $install)
diff --git a/app/Services/ApprovedAnchorTerritories.php b/app/Services/ApprovedAnchorTerritories.php
new file mode 100644
index 00000000..6ef2ac54
--- /dev/null
+++ b/app/Services/ApprovedAnchorTerritories.php
@@ -0,0 +1,103 @@
+>,links:list>} */
+ public function plan(): array
+ {
+ $file = base_path('docs/investmoz/unification/approved-anchor-territories-20261023.json');
+ $contents = is_file($file) ? file_get_contents($file) : false;
+ if ($contents === false || ! hash_equals(self::HASH, hash('sha256', $contents))) {
+ throw new RuntimeException('Reviewed territorial manifest changed.');
+ }
+ $manifest = json_decode($contents, true, 512, JSON_THROW_ON_ERROR);
+ if (count($manifest['items']) !== 28) {
+ throw new RuntimeException('Exact 28-link scope required.');
+ }
+ $projects = [];
+ $links = [];
+ foreach ($manifest['items'] as $item) {
+ $project = DB::table('projects')->where('id', $item['project_id'])->whereNull('deleted_at')->first();
+ $dossier = DB::table('investment_dossiers')->where('id', $item['dossier_id'])->whereNull('deleted_at')->first();
+ if (! $project || $project->code !== $item['code'] || ! $dossier || $dossier->project_id !== $project->id
+ || ! hash_equals($item['content_sha256'], hash('sha256', $dossier->content))
+ || ! hash_equals($item['source_sha256'], hash('sha256', $dossier->source))) {
+ throw new RuntimeException('Project identity or documentary source changed: '.$item['code']);
+ }
+ $original = $item['original_relation'];
+ $geo = DB::table('geo_locations')->where('id', $original['geo_location_id'])->whereNull('deleted_at')->first();
+ foreach (['location_type', 'source_code', 'parent_id', 'data_classification'] as $field) {
+ if (! $geo || $item['territory'][$field] !== $geo->$field) {
+ throw new RuntimeException('Territory identity changed: '.$original['geo_location_id']);
+ }
+ }
+ $metadata = $projects[$project->id]['after_metadata'] ?? json_decode($project->metadata, true, 512, JSON_THROW_ON_ERROR);
+ $key = $geo->id.':'.$original['role'];
+ $evidence = $item['evidence'];
+ // Preserve the original dossier id in evidence and explicitly map the destination.
+ $evidence['transported_dossier_id'] = $dossier->id;
+ if (isset($metadata['documented_location_sources'][$key]) && $metadata['documented_location_sources'][$key] != $evidence) {
+ throw new RuntimeException('Existing territorial evidence differs; no overwrite: '.$item['code']);
+ }
+ $projects[$project->id] ??= ['id' => $project->id, 'code' => $project->code, 'before_version' => (int) $project->version_no, 'before_metadata' => json_decode($project->metadata, true, 512, JSON_THROW_ON_ERROR)];
+ $metadata['documented_location_sources'][$key] = $evidence;
+ $projects[$project->id]['after_metadata'] = $metadata;
+ $existing = DB::table('project_locations')->where('project_id', $project->id)->where('geo_location_id', $geo->id)->where('role', $original['role'])->first();
+ if ($existing && ($existing->deleted_at || $existing->data_classification !== 'public')) {
+ throw new RuntimeException('Archived or restricted territorial relation must not be revived.');
+ }
+ $identity = DB::table('project_locations')->where('id', $original['id'])->first();
+ if ($identity && (! $existing || $identity->id !== $existing->id)) {
+ throw new RuntimeException('Historical relation identity is already occupied.');
+ }
+ $links[] = ['code' => $item['code'], 'already_present' => (bool) $existing, 'row' => [...$original, 'project_id' => $project->id]];
+ }
+
+ return ['manifest_sha256' => self::HASH, 'projects' => array_values($projects), 'links' => $links];
+ }
+
+ /** Caller supplies an authenticated, backed-up transaction; no source publication changes.
+ * @param array{manifest_sha256:string,projects:list>,links:list>} $plan
+ * @return array
+ */
+ public function apply(array $plan): array
+ {
+ if (DB::transactionLevel() < 1 || $this->plan() !== $plan) {
+ throw new RuntimeException('Reviewed transaction and unchanged preview required.');
+ }
+ $inserted = 0;
+ $updated = 0;
+ foreach ($plan['projects'] as $project) {
+ if ($project['before_metadata'] == $project['after_metadata']) {
+ continue;
+ }
+ $count = DB::table('projects')->where('id', $project['id'])->where('version_no', $project['before_version'])->update([
+ 'metadata' => json_encode($project['after_metadata'], JSON_THROW_ON_ERROR), 'version_no' => $project['before_version'] + 1, 'updated_at' => now(),
+ ]);
+ if ($count !== 1) {
+ throw new RuntimeException('Concurrent project change.');
+ }
+ DB::table('audit_events')->insert(['source_system' => 'approved-anchor-territories-recovery-v1', 'external_id' => self::HASH.':'.$project['id'], 'entity_type' => 'projects', 'entity_id' => $project['id'], 'action' => 'accepted_territories_restored',
+ 'data_classification' => 'public', 'before_data' => json_encode(['version_no' => $project['before_version'], 'metadata' => $project['before_metadata']], JSON_THROW_ON_ERROR),
+ 'after_data' => json_encode(['version_no' => $project['before_version'] + 1, 'manifest_sha256' => self::HASH, 'metadata' => $project['after_metadata'], 'new_approval' => false], JSON_THROW_ON_ERROR)]);
+ $updated++;
+ }
+ foreach ($plan['links'] as $link) {
+ if ($link['already_present']) {
+ continue;
+ }
+ DB::table('project_locations')->insert($link['row']);
+ $inserted++;
+ }
+
+ return ['relations_restored' => $inserted, 'projects_updated' => $updated, 'new_dossiers' => 0, 'publication_changes' => 0];
+ }
+}
diff --git a/app/Services/InvestorContext.php b/app/Services/InvestorContext.php
index 1be96221..2fea1b36 100644
--- a/app/Services/InvestorContext.php
+++ b/app/Services/InvestorContext.php
@@ -122,6 +122,7 @@ final class InvestorContext
public function dependencyHash(array $selection): string
{
+ unset($selection['portfolio'], $selection['selection']['portfolio']);
if (isset($selection['opportunity_choices'])) $selection['opportunity_choices'] = array_map(fn($choice)=>Arr::except($choice,['portfolio_origins']),$selection['opportunity_choices']);
return hash('sha256', json_encode(Arr::sortRecursive($selection), JSON_THROW_ON_ERROR));
}
@@ -168,6 +169,18 @@ final class InvestorContext
if ($o->primary_territory_id) {
$fields = [...$fields, ...$this->territoryFields($o->primary_territory_id)];
}
+ } elseif ($kind === 'portfolio') {
+ abort_unless(Str::isUuid($id), 422);
+ $dossier = \App\Http\Controllers\InvestmentPortfolioController::visible()->findOrFail($id);
+ $title = $dossier->title;
+ $href = '/carteira/'.$id;
+ // Documentary coverage is not the investor's chosen implantation.
+ $version = DB::table('investment_dossiers')->where('id', $id)->value('version_no');
+ $fields = ['project_title' => $title, 'project_summary' => $dossier->content['description'] ?? $dossier->content['focus'] ?? ''];
+ $state = 'documented_origin';
+ $zoneAnalysis = ['source' => $dossier->source, 'documented_sector' => $dossier->content['sector'] ?? null,
+ 'documented_location' => $dossier->content['location'] ?? $dossier->content['region'] ?? null,
+ 'geography' => app(InvestmentRelations::class)->dossier($dossier), 'available_opportunity' => false];
} elseif ($kind === 'business') {
abort_unless(config('existing-business.enabled') && Str::isUuid($id), 404);
$o = ExistingBusiness::published()->with('sector')->findOrFail($id);
@@ -354,7 +367,7 @@ final class InvestorContext
'opportunity_choices.*.park' => 'sometimes|nullable|string|max:100',
'opportunity_choices.*.source' => 'required|string|distinct|max:100', 'opportunity_choices.*.territory' => 'nullable|string|max:100',
'opportunity_choices.*.location_reason' => 'nullable|string|max:2000', 'opportunity_choices.*.confirm_location_change' => 'sometimes|boolean',
- 'version' => 'required|integer|min:1', 'selection' => 'present|array:opportunity,sector,territory,park',
+ 'version' => 'required|integer|min:1', 'selection' => 'present|array:portfolio,opportunity,sector,territory,park',
'selection.*' => 'nullable|string|max:100', 'declarations' => 'nullable|array:project_title,project_summary,currency,expected_start_date,investor_origin,person_type,entity_stage,tax_residency_country,fiscal_residency_country,project_type,maturity_stage,'.implode(',', PrivateInvestmentPreparation::FIELDS), 'declarations.project_title' => 'nullable|string|max:200', 'declarations.project_summary' => 'nullable|string|max:5000',
'declarations.currency' => 'nullable|regex:/^[A-Z]{3}$/', 'declarations.expected_start_date' => 'nullable|date_format:Y-m-d', 'declarations.investor_origin' => 'nullable|in:national,foreign,mixed', 'declarations.person_type' => 'nullable|in:singular,collective,sole_trader,consortium', 'declarations.entity_stage' => 'nullable|in:existing,being_formed', 'declarations.tax_residency_country' => ['nullable', 'string', app(CountryCatalogue::class)->rule()], 'declarations.fiscal_residency_country' => ['nullable', 'string', app(CountryCatalogue::class)->rule()], 'declarations.project_type' => 'nullable|string|max:100', 'declarations.maturity_stage' => 'nullable|string|max:100',
'replace_fields' => 'nullable|array', 'replace_fields.*' => 'string|in:'.implode(',', self::FIELDS)])->validate();
@@ -432,7 +445,7 @@ final class InvestorContext
}
$proposed = [];
$origins = [];
- foreach (['opportunity', 'sector', 'park', 'territory'] as $slot) {
+ foreach (['portfolio', 'opportunity', 'sector', 'park', 'territory'] as $slot) {
if (in_array($slot, ['park', 'territory'], true) && array_intersect(array_keys($selection[$slot]['fields'] ?? []), array_keys(InvestmentGeography::FIELDS))) {
foreach (['province_id', 'district_id', 'admin_post_id', 'locality_id', 'province', 'district', 'location'] as $key) {
unset($proposed[$key],$origins[$key]);
@@ -484,7 +497,7 @@ final class InvestorContext
$replaced[] = ['field' => $key, 'before' => $old['fields'][$key] ?? null, 'after' => $fields[$key] ?? null];
}
}
- foreach (['opportunity', 'sector', 'territory', 'park'] as $slot) {
+ foreach (['portfolio', 'opportunity', 'sector', 'territory', 'park'] as $slot) {
if (($old['selection'][$slot] ?? null) !== ($selection[$slot] ?? null)) {
$changed[] = $slot;
}
@@ -657,6 +670,7 @@ final class InvestorContext
$sim['context_applicability_snapshot'] = json_encode([
'version' => 1, 'context_revision' => $ctx['revision'],
'consumer_opportunity' => $ctx['consumer_opportunity']['opportunity']['key'] ?? null,
+ 'portfolio_origin' => $ctx['selection']['portfolio'] ?? null,
'zone' => $zone ? Arr::only($zone, ['id', 'title', 'href', 'version', 'sha256', 'fields', 'analysis']) : null,
'provenance' => $ctx['provenance'],
'opportunity_choices' => $ctx['opportunity_choices'] ?? [],
diff --git a/docs/investmoz/unification/anchor-integration-receipt-20261023.json b/docs/investmoz/unification/anchor-integration-receipt-20261023.json
new file mode 100644
index 00000000..6344bca1
--- /dev/null
+++ b/docs/investmoz/unification/anchor-integration-receipt-20261023.json
@@ -0,0 +1,136 @@
+{
+ "status": "implemented_and_demonstrated_in_isolated_QA_not_yet_delivered",
+ "date": "2026-10-23",
+ "base": "8036b9b0",
+ "accepted_delivery_receipt": "cdf8fcfb",
+ "active_comparison": {
+ "database": {
+ "database": "teste_investidor",
+ "port": 5432,
+ "role": "teste_investidor_app"
+ },
+ "read_only": "on",
+ "published_fiches": 29,
+ "cluster_relations": 13,
+ "project_locations": 0,
+ "RLS": [
+ {
+ "relname": "projects",
+ "relrowsecurity": false,
+ "relforcerowsecurity": false
+ },
+ {
+ "relname": "project_locations",
+ "relrowsecurity": false,
+ "relforcerowsecurity": false
+ },
+ {
+ "relname": "cluster_projects",
+ "relrowsecurity": false,
+ "relforcerowsecurity": false
+ },
+ {
+ "relname": "investment_dossiers",
+ "relrowsecurity": false,
+ "relforcerowsecurity": false
+ },
+ {
+ "relname": "opportunity_projects",
+ "relrowsecurity": false,
+ "relforcerowsecurity": false
+ }
+ ],
+ "missing_accepted_locations": 28,
+ "source_inventory": "inventory-20261007-172113.json",
+ "cause_scope": "Transported project identities omit accepted territorial rows and citation metadata; visibility recovery only restored publication status. Exact event/time not established."
+ },
+ "qa_recovery": {
+ "mode": "applied",
+ "database": "simulator_fiscal_delta_20261021_test",
+ "port": 55441,
+ "qa": true,
+ "manifest_sha256": "dc3ae2014da51005d95780e2e4ae87e55e000e66e0765f0671c6e44a958026a0",
+ "preview_sha256": "601a8603cf39f51a22cef9195e238a21c1552cb3303672b78ec52826c6342b57",
+ "relations": 28,
+ "projects": 13,
+ "relations_restored": 28,
+ "projects_updated": 13,
+ "new_dossiers": 0,
+ "publication_changes": 0
+ },
+ "tests": {
+ "php": {
+ "tests": 4,
+ "assertions": 116,
+ "passed": 4
+ },
+ "frontend": {
+ "tests": 2,
+ "passed": 2
+ },
+ "typescript": "passed",
+ "build": "passed",
+ "phpstan_new_recovery_service": "passed, zero errors"
+ },
+ "backup": {
+ "stage": "/var/backups/investmoz-anchor-integration-20261023/backup",
+ "target": {
+ "database": "teste_investidor",
+ "port": 5432
+ },
+ "tables": 174,
+ "files_verified": 369,
+ "dump_sha256": "207ff14c6af7c4b2dd280def898945cb58314e01930b51c50d502e95cbe6ac68",
+ "files_sha256": "8cd85ab7d5a772452111e4fe7feab48f7fc694ee3f0fbd264f50096254835fe2",
+ "restore_verified": false
+ },
+ "isolated_restore": {
+ "restore_verified": true,
+ "tables_verified": 174,
+ "container_network": "none",
+ "database": "anchor_restore_20261023",
+ "port": 55441,
+ "source_dump_sha256": "207ff14c6af7c4b2dd280def898945cb58314e01930b51c50d502e95cbe6ac68",
+ "active_database_writes": 0
+ },
+ "preserved_closures": [
+ "6b544548",
+ "d8224ba8",
+ "55136b44",
+ "8036b9b0"
+ ],
+ "not_repeated": [
+ "native saved PDF",
+ "Word",
+ "ZIP",
+ "accepted portfolio via opportunity branch",
+ "accepted complements and four consumers"
+ ],
+ "deferred": [
+ "statistics",
+ "AI"
+ ],
+ "pending": [
+ "Git integration and installation",
+ "Exact territorial recovery in homologation",
+ "Installed delta check"
+ ],
+ "screenshots": [
+ "outputs/anchor-integration-20261023/qa-sector-location.png",
+ "outputs/anchor-integration-20261023/qa-anchor-fiche.png",
+ "outputs/anchor-integration-20261023/qa-anchor-dossier.png",
+ "outputs/anchor-integration-20261023/qa-anchor-simulator.png"
+ ],
+ "visual_QA": {
+ "anchor_code": "A06",
+ "anchor_fiche": "57a4ee7a-4c07-4e26-b8f5-e07726e41512",
+ "case_id": "3fd1bac6-80cf-48c8-97f3-eb4bb3398a17",
+ "simulation_draft_id": "bbc9ae3d-8c0e-45d2-b93f-9eaa85bab4d4",
+ "sector": "Agronegócio",
+ "province": "Sofala",
+ "offer_invented": false,
+ "deliberate_title_preserved": true,
+ "source_link_visible_in_dossier_and_simulator": true,
+ "manifestation": "HTTP directed proof, including ownership, same-source identity and versioned binding; browser native confirmation cancelled after control timeout; no formal submission"
+ }
+}
diff --git a/docs/investmoz/unification/approved-anchor-territories-20261023.json b/docs/investmoz/unification/approved-anchor-territories-20261023.json
new file mode 100644
index 00000000..a95d3d25
--- /dev/null
+++ b/docs/investmoz/unification/approved-anchor-territories-20261023.json
@@ -0,0 +1,1073 @@
+{
+ "format": "approved-anchor-territories-recovery-v1",
+ "instruction": "Tempo 23/10/2026: preserve and restore accepted functionality, using existing receipts; no new publication or invented association",
+ "accepted_at": "2026-10-07T12:59:36Z",
+ "source_inventory_sha256": "6904486ee9c3895ee5e42d9ef19e6cb5f223930f7734a7af18051053d019cda6",
+ "source_inventory": "anchor-project-reconciliation/inventory-20261007-172113.json",
+ "items": [
+ {
+ "code": "A03",
+ "source_project_id": "10a6e456-b287-4cf7-9ce6-ccd4e28a0684",
+ "project_id": "9f896734-0e33-4d1e-8951-2318333b04f9",
+ "dossier_id": "6c03e980-c455-49cc-a3be-99d29014e91d",
+ "content_sha256": "75266ff89da58e4d6e5422e49e4641c62dae4f171fa358b70e210c5883a1fd07",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "4e4ea1e5-eb2a-41be-a7ae-2e9a7c76d369",
+ "source_system": "documented-relations-repair",
+ "external_id": "39f5973c-f4cd-49d0-aeea-1c0c71783550:33a98ebf-f98c-53d1-a047-32ccd9c4cd98:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "10a6e456-b287-4cf7-9ce6-ccd4e28a0684",
+ "geo_location_id": "33a98ebf-f98c-53d1-a047-32ccd9c4cd98",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "33a98ebf-f98c-53d1-a047-32ccd9c4cd98",
+ "name": "Nampula",
+ "location_type": "province",
+ "source_code": "03",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "39f5973c-f4cd-49d0-aeea-1c0c71783550",
+ "source_quote": "Corredor de Nacala: Nampula, Cabo Delgado, Niassa, Tete e Norte da Zambézia, incluindo Nacala, Nampula, Cuamba, Palma e áreas ligadas ao corredor.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A03",
+ "source_project_id": "10a6e456-b287-4cf7-9ce6-ccd4e28a0684",
+ "project_id": "9f896734-0e33-4d1e-8951-2318333b04f9",
+ "dossier_id": "6c03e980-c455-49cc-a3be-99d29014e91d",
+ "content_sha256": "75266ff89da58e4d6e5422e49e4641c62dae4f171fa358b70e210c5883a1fd07",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "7065fb75-09ee-48c4-867d-c14fe8242c13",
+ "source_system": "documented-relations-repair",
+ "external_id": "39f5973c-f4cd-49d0-aeea-1c0c71783550:059b02ca-7095-577a-8705-4d4c46896747:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "10a6e456-b287-4cf7-9ce6-ccd4e28a0684",
+ "geo_location_id": "059b02ca-7095-577a-8705-4d4c46896747",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "059b02ca-7095-577a-8705-4d4c46896747",
+ "name": "Cabo Delgado",
+ "location_type": "province",
+ "source_code": "02",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "39f5973c-f4cd-49d0-aeea-1c0c71783550",
+ "source_quote": "Corredor de Nacala: Nampula, Cabo Delgado, Niassa, Tete e Norte da Zambézia, incluindo Nacala, Nampula, Cuamba, Palma e áreas ligadas ao corredor.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A03",
+ "source_project_id": "10a6e456-b287-4cf7-9ce6-ccd4e28a0684",
+ "project_id": "9f896734-0e33-4d1e-8951-2318333b04f9",
+ "dossier_id": "6c03e980-c455-49cc-a3be-99d29014e91d",
+ "content_sha256": "75266ff89da58e4d6e5422e49e4641c62dae4f171fa358b70e210c5883a1fd07",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "af18085a-49cd-4c36-9029-a6b0455f2ad3",
+ "source_system": "documented-relations-repair",
+ "external_id": "39f5973c-f4cd-49d0-aeea-1c0c71783550:7d908cf8-6e52-5141-8832-b1193985e39f:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "10a6e456-b287-4cf7-9ce6-ccd4e28a0684",
+ "geo_location_id": "7d908cf8-6e52-5141-8832-b1193985e39f",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "7d908cf8-6e52-5141-8832-b1193985e39f",
+ "name": "Niassa",
+ "location_type": "province",
+ "source_code": "01",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "39f5973c-f4cd-49d0-aeea-1c0c71783550",
+ "source_quote": "Corredor de Nacala: Nampula, Cabo Delgado, Niassa, Tete e Norte da Zambézia, incluindo Nacala, Nampula, Cuamba, Palma e áreas ligadas ao corredor.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A03",
+ "source_project_id": "10a6e456-b287-4cf7-9ce6-ccd4e28a0684",
+ "project_id": "9f896734-0e33-4d1e-8951-2318333b04f9",
+ "dossier_id": "6c03e980-c455-49cc-a3be-99d29014e91d",
+ "content_sha256": "75266ff89da58e4d6e5422e49e4641c62dae4f171fa358b70e210c5883a1fd07",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "844724ab-05c2-4ae8-be88-6d01dff6047d",
+ "source_system": "documented-relations-repair",
+ "external_id": "39f5973c-f4cd-49d0-aeea-1c0c71783550:c0a78e45-ebaa-590e-847f-8ba68e4b2fbe:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "10a6e456-b287-4cf7-9ce6-ccd4e28a0684",
+ "geo_location_id": "c0a78e45-ebaa-590e-847f-8ba68e4b2fbe",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "c0a78e45-ebaa-590e-847f-8ba68e4b2fbe",
+ "name": "Tete",
+ "location_type": "province",
+ "source_code": "05",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "39f5973c-f4cd-49d0-aeea-1c0c71783550",
+ "source_quote": "Corredor de Nacala: Nampula, Cabo Delgado, Niassa, Tete e Norte da Zambézia, incluindo Nacala, Nampula, Cuamba, Palma e áreas ligadas ao corredor.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A03",
+ "source_project_id": "10a6e456-b287-4cf7-9ce6-ccd4e28a0684",
+ "project_id": "9f896734-0e33-4d1e-8951-2318333b04f9",
+ "dossier_id": "6c03e980-c455-49cc-a3be-99d29014e91d",
+ "content_sha256": "75266ff89da58e4d6e5422e49e4641c62dae4f171fa358b70e210c5883a1fd07",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "9737ecb0-c52c-4efb-8142-aa421db4e00c",
+ "source_system": "documented-relations-repair",
+ "external_id": "39f5973c-f4cd-49d0-aeea-1c0c71783550:c20efcce-8af8-588d-84b2-b4b138b6e066:impact",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "10a6e456-b287-4cf7-9ce6-ccd4e28a0684",
+ "geo_location_id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "role": "impact"
+ },
+ "territory": {
+ "id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "name": "Zambezia",
+ "location_type": "province",
+ "source_code": "04",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Referência parcial ao Norte da Zambézia; não representa cobertura integral da província",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "39f5973c-f4cd-49d0-aeea-1c0c71783550",
+ "source_quote": "Corredor de Nacala: Nampula, Cabo Delgado, Niassa, Tete e Norte da Zambézia, incluindo Nacala, Nampula, Cuamba, Palma e áreas ligadas ao corredor.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A04",
+ "source_project_id": "425ddc38-8e4e-4c79-8c58-2fc011b5fb56",
+ "project_id": "178f6b83-0b51-42ef-b8ef-b28f9ca3f73f",
+ "dossier_id": "8bd83cc4-b36c-46cd-9287-b47e1162b578",
+ "content_sha256": "f6a63e2ee2f2e7c98f1030d206996ad57b0d92129d021ed3c6bb53f161d56f5b",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "7ea5a964-3d89-42e4-a5c9-d5b85d6c5c58",
+ "source_system": "documented-relations-repair",
+ "external_id": "0dccdd26-9796-4ef7-947b-5a2970ace379:33a98ebf-f98c-53d1-a047-32ccd9c4cd98:primary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "425ddc38-8e4e-4c79-8c58-2fc011b5fb56",
+ "geo_location_id": "33a98ebf-f98c-53d1-a047-32ccd9c4cd98",
+ "role": "primary"
+ },
+ "territory": {
+ "id": "33a98ebf-f98c-53d1-a047-32ccd9c4cd98",
+ "name": "Nampula",
+ "location_type": "province",
+ "source_code": "03",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "0dccdd26-9796-4ef7-947b-5a2970ace379",
+ "source_quote": "Crusse Jamali, zona de Nacala, província de Nampula.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A05",
+ "source_project_id": "b6a2dad3-9f8b-4f5b-a120-38cb48e6f055",
+ "project_id": "c914bf6d-49d3-4f98-92ec-726f79a488da",
+ "dossier_id": "d8a88bac-4684-43fa-aea6-e54fef9b8a47",
+ "content_sha256": "ea0f6b7843289d81dc2852327432721f8677e28ad8b41d754abc8c91307303d3",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "8ae35b8f-e448-4677-8378-266b3b5323d4",
+ "source_system": "documented-relations-repair",
+ "external_id": "361789ad-1e14-4b64-8f1f-fad053886d5a:33a98ebf-f98c-53d1-a047-32ccd9c4cd98:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "b6a2dad3-9f8b-4f5b-a120-38cb48e6f055",
+ "geo_location_id": "33a98ebf-f98c-53d1-a047-32ccd9c4cd98",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "33a98ebf-f98c-53d1-a047-32ccd9c4cd98",
+ "name": "Nampula",
+ "location_type": "province",
+ "source_code": "03",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "361789ad-1e14-4b64-8f1f-fad053886d5a",
+ "source_quote": "Eixo Namialo–Metoro, entre as províncias de Nampula e Cabo Delgado, com ligações a Pemba e Palma.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A05",
+ "source_project_id": "b6a2dad3-9f8b-4f5b-a120-38cb48e6f055",
+ "project_id": "c914bf6d-49d3-4f98-92ec-726f79a488da",
+ "dossier_id": "d8a88bac-4684-43fa-aea6-e54fef9b8a47",
+ "content_sha256": "ea0f6b7843289d81dc2852327432721f8677e28ad8b41d754abc8c91307303d3",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "483ec6c5-9b95-4242-b2f8-7d3b908187eb",
+ "source_system": "documented-relations-repair",
+ "external_id": "361789ad-1e14-4b64-8f1f-fad053886d5a:059b02ca-7095-577a-8705-4d4c46896747:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "b6a2dad3-9f8b-4f5b-a120-38cb48e6f055",
+ "geo_location_id": "059b02ca-7095-577a-8705-4d4c46896747",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "059b02ca-7095-577a-8705-4d4c46896747",
+ "name": "Cabo Delgado",
+ "location_type": "province",
+ "source_code": "02",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "361789ad-1e14-4b64-8f1f-fad053886d5a",
+ "source_quote": "Eixo Namialo–Metoro, entre as províncias de Nampula e Cabo Delgado, com ligações a Pemba e Palma.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A06",
+ "source_project_id": "56901822-cf37-47bb-b33f-e83488c481ea",
+ "project_id": "da9888c0-dbc8-4f8a-bf2d-e0666daea878",
+ "dossier_id": "57a4ee7a-4c07-4e26-b8f5-e07726e41512",
+ "content_sha256": "c7fae7b2ca541e734e587589dace8dc85dee2494876de6e30ecd91a7177a985d",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "32fffbd4-2646-43b5-9e6b-e7e84b453981",
+ "source_system": "documented-relations-repair",
+ "external_id": "15474e6a-90a3-4db4-b456-eb1c1c66227c:c0a78e45-ebaa-590e-847f-8ba68e4b2fbe:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "56901822-cf37-47bb-b33f-e83488c481ea",
+ "geo_location_id": "c0a78e45-ebaa-590e-847f-8ba68e4b2fbe",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "c0a78e45-ebaa-590e-847f-8ba68e4b2fbe",
+ "name": "Tete",
+ "location_type": "province",
+ "source_code": "05",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "15474e6a-90a3-4db4-b456-eb1c1c66227c",
+ "source_quote": "Províncias de Tete, Manica, Zambézia e Sofala, articuladas pelos corredores da Beira e de Nacala e pelas bacias de irrigação identificadas.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A06",
+ "source_project_id": "56901822-cf37-47bb-b33f-e83488c481ea",
+ "project_id": "da9888c0-dbc8-4f8a-bf2d-e0666daea878",
+ "dossier_id": "57a4ee7a-4c07-4e26-b8f5-e07726e41512",
+ "content_sha256": "c7fae7b2ca541e734e587589dace8dc85dee2494876de6e30ecd91a7177a985d",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "87f02cb5-4e61-4053-8bf7-85e3fc467b22",
+ "source_system": "documented-relations-repair",
+ "external_id": "15474e6a-90a3-4db4-b456-eb1c1c66227c:cf5e81f1-ffbc-535d-b1b6-b44b445c4421:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "56901822-cf37-47bb-b33f-e83488c481ea",
+ "geo_location_id": "cf5e81f1-ffbc-535d-b1b6-b44b445c4421",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "cf5e81f1-ffbc-535d-b1b6-b44b445c4421",
+ "name": "Manica",
+ "location_type": "province",
+ "source_code": "06",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "15474e6a-90a3-4db4-b456-eb1c1c66227c",
+ "source_quote": "Províncias de Tete, Manica, Zambézia e Sofala, articuladas pelos corredores da Beira e de Nacala e pelas bacias de irrigação identificadas.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A06",
+ "source_project_id": "56901822-cf37-47bb-b33f-e83488c481ea",
+ "project_id": "da9888c0-dbc8-4f8a-bf2d-e0666daea878",
+ "dossier_id": "57a4ee7a-4c07-4e26-b8f5-e07726e41512",
+ "content_sha256": "c7fae7b2ca541e734e587589dace8dc85dee2494876de6e30ecd91a7177a985d",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "f8e0ad76-2d77-4801-95f5-4541797c8173",
+ "source_system": "documented-relations-repair",
+ "external_id": "15474e6a-90a3-4db4-b456-eb1c1c66227c:c20efcce-8af8-588d-84b2-b4b138b6e066:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "56901822-cf37-47bb-b33f-e83488c481ea",
+ "geo_location_id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "name": "Zambezia",
+ "location_type": "province",
+ "source_code": "04",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "15474e6a-90a3-4db4-b456-eb1c1c66227c",
+ "source_quote": "Províncias de Tete, Manica, Zambézia e Sofala, articuladas pelos corredores da Beira e de Nacala e pelas bacias de irrigação identificadas.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A06",
+ "source_project_id": "56901822-cf37-47bb-b33f-e83488c481ea",
+ "project_id": "da9888c0-dbc8-4f8a-bf2d-e0666daea878",
+ "dossier_id": "57a4ee7a-4c07-4e26-b8f5-e07726e41512",
+ "content_sha256": "c7fae7b2ca541e734e587589dace8dc85dee2494876de6e30ecd91a7177a985d",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "d0189150-c4ec-446b-8850-d49e44de4e6f",
+ "source_system": "documented-relations-repair",
+ "external_id": "15474e6a-90a3-4db4-b456-eb1c1c66227c:f57ff041-6275-57b9-8800-c35e46e0d475:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "56901822-cf37-47bb-b33f-e83488c481ea",
+ "geo_location_id": "f57ff041-6275-57b9-8800-c35e46e0d475",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "f57ff041-6275-57b9-8800-c35e46e0d475",
+ "name": "Sofala",
+ "location_type": "province",
+ "source_code": "07",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "15474e6a-90a3-4db4-b456-eb1c1c66227c",
+ "source_quote": "Províncias de Tete, Manica, Zambézia e Sofala, articuladas pelos corredores da Beira e de Nacala e pelas bacias de irrigação identificadas.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A07",
+ "source_project_id": "4a9b3192-0f73-409f-8e82-a6a3dbffba89",
+ "project_id": "0b68f923-2cc6-445d-8e02-3465f3d23e49",
+ "dossier_id": "70ae731e-fdef-473f-b495-14f319b28d60",
+ "content_sha256": "3eb01ce3dd2cc68b43b816708f7e5f990c48f1aea6555cdfd169a286e11b9bd4",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "8d539dd7-38dd-4650-a9c5-65b52caa958e",
+ "source_system": "documented-relations-repair",
+ "external_id": "22323abb-91d9-43ed-98f3-1194a5250c9e:f57ff041-6275-57b9-8800-c35e46e0d475:primary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "4a9b3192-0f73-409f-8e82-a6a3dbffba89",
+ "geo_location_id": "f57ff041-6275-57b9-8800-c35e46e0d475",
+ "role": "primary"
+ },
+ "territory": {
+ "id": "f57ff041-6275-57b9-8800-c35e46e0d475",
+ "name": "Sofala",
+ "location_type": "province",
+ "source_code": "07",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "22323abb-91d9-43ed-98f3-1194a5250c9e",
+ "source_quote": "Região Centro, com incidência principal em Sofala e articulação produtiva com Manica e Tete, junto ao Corredor da Beira.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A07",
+ "source_project_id": "4a9b3192-0f73-409f-8e82-a6a3dbffba89",
+ "project_id": "0b68f923-2cc6-445d-8e02-3465f3d23e49",
+ "dossier_id": "70ae731e-fdef-473f-b495-14f319b28d60",
+ "content_sha256": "3eb01ce3dd2cc68b43b816708f7e5f990c48f1aea6555cdfd169a286e11b9bd4",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "4d5ec80d-ed13-431a-8457-664aacd32856",
+ "source_system": "documented-relations-repair",
+ "external_id": "22323abb-91d9-43ed-98f3-1194a5250c9e:cf5e81f1-ffbc-535d-b1b6-b44b445c4421:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "4a9b3192-0f73-409f-8e82-a6a3dbffba89",
+ "geo_location_id": "cf5e81f1-ffbc-535d-b1b6-b44b445c4421",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "cf5e81f1-ffbc-535d-b1b6-b44b445c4421",
+ "name": "Manica",
+ "location_type": "province",
+ "source_code": "06",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "22323abb-91d9-43ed-98f3-1194a5250c9e",
+ "source_quote": "Região Centro, com incidência principal em Sofala e articulação produtiva com Manica e Tete, junto ao Corredor da Beira.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A07",
+ "source_project_id": "4a9b3192-0f73-409f-8e82-a6a3dbffba89",
+ "project_id": "0b68f923-2cc6-445d-8e02-3465f3d23e49",
+ "dossier_id": "70ae731e-fdef-473f-b495-14f319b28d60",
+ "content_sha256": "3eb01ce3dd2cc68b43b816708f7e5f990c48f1aea6555cdfd169a286e11b9bd4",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "e85721fd-de4a-4021-80ea-5600a25a03a5",
+ "source_system": "documented-relations-repair",
+ "external_id": "22323abb-91d9-43ed-98f3-1194a5250c9e:c0a78e45-ebaa-590e-847f-8ba68e4b2fbe:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "4a9b3192-0f73-409f-8e82-a6a3dbffba89",
+ "geo_location_id": "c0a78e45-ebaa-590e-847f-8ba68e4b2fbe",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "c0a78e45-ebaa-590e-847f-8ba68e4b2fbe",
+ "name": "Tete",
+ "location_type": "province",
+ "source_code": "05",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "22323abb-91d9-43ed-98f3-1194a5250c9e",
+ "source_quote": "Região Centro, com incidência principal em Sofala e articulação produtiva com Manica e Tete, junto ao Corredor da Beira.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A08",
+ "source_project_id": "1169d03c-fe38-47c5-a54c-286a3f126ce4",
+ "project_id": "c90912e9-c4ed-4ee7-b11f-f8d153020501",
+ "dossier_id": "b30ecd8c-220d-4c7a-b1a7-704dc24d0933",
+ "content_sha256": "bca089a4bb2601ca34c50e2c48068b4c2f9fa7a873955cf0587f261a83c2a146",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "2eea9f18-389c-42b5-ba39-d3d10816b50f",
+ "source_system": "documented-relations-repair",
+ "external_id": "81d775e5-5dff-4fa2-98b1-72affb0a1082:c20efcce-8af8-588d-84b2-b4b138b6e066:primary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "1169d03c-fe38-47c5-a54c-286a3f126ce4",
+ "geo_location_id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "role": "primary"
+ },
+ "territory": {
+ "id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "name": "Zambezia",
+ "location_type": "province",
+ "source_code": "04",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "81d775e5-5dff-4fa2-98b1-72affb0a1082",
+ "source_quote": "Mocuba e Munhamade, província da Zambézia, com ligações a Quelimane, Nacala, Caia e Milange.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A09",
+ "source_project_id": "dda21e48-1b36-4d6c-b03b-b594b1ef16c4",
+ "project_id": "4dfeaec8-68b1-4ba7-afc2-aaca16b8b06e",
+ "dossier_id": "dc8892ff-fdda-480c-81f1-2ffe0bfcb40b",
+ "content_sha256": "7e3bb071f65e49245fbfd070f4123ac49985004e865c475bf7e34c85cc708aea",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "630cf7eb-44fa-4bac-861c-2c923f21f27a",
+ "source_system": "documented-relations-repair",
+ "external_id": "67263220-6849-468f-82f4-d5e1f5617190:c20efcce-8af8-588d-84b2-b4b138b6e066:primary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "dda21e48-1b36-4d6c-b03b-b594b1ef16c4",
+ "geo_location_id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "role": "primary"
+ },
+ "territory": {
+ "id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "name": "Zambezia",
+ "location_type": "province",
+ "source_code": "04",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "67263220-6849-468f-82f4-d5e1f5617190",
+ "source_quote": "Cidade de Mocuba, província da Zambézia.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A10",
+ "source_project_id": "3fc0814d-48d0-423a-8ada-95662a204b14",
+ "project_id": "042e7700-3526-4c90-9d17-bef964e36f9f",
+ "dossier_id": "77b685f0-848f-4800-83f8-a29539ed8f31",
+ "content_sha256": "02dc0fb152908e81b11304f6bc0c2252805ebd2ad1860b1a6bfa918e2cbcd5bb",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "e8e0ff7c-9629-44a7-bedb-c1a71a8cd816",
+ "source_system": "documented-relations-repair",
+ "external_id": "cad01a02-6072-4a11-823a-1ae379bc65da:c0a78e45-ebaa-590e-847f-8ba68e4b2fbe:primary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "3fc0814d-48d0-423a-8ada-95662a204b14",
+ "geo_location_id": "c0a78e45-ebaa-590e-847f-8ba68e4b2fbe",
+ "role": "primary"
+ },
+ "territory": {
+ "id": "c0a78e45-ebaa-590e-847f-8ba68e4b2fbe",
+ "name": "Tete",
+ "location_type": "province",
+ "source_code": "05",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "cad01a02-6072-4a11-823a-1ae379bc65da",
+ "source_quote": "Rio Zambeze, província de Tete, a jusante da Hidroeléctrica de Cahora Bassa; área exacta sujeita à documentação oficial do projecto.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A11",
+ "source_project_id": "9c2398a0-e3ae-4225-b198-2eec9674a37f",
+ "project_id": "54f80879-0fcc-4bc9-9612-c6fcefd26e69",
+ "dossier_id": "cb125f84-6f75-48e5-a0de-2f5e6bd537ed",
+ "content_sha256": "736fc41d941740f41697c579ffe6c4208d45005d7177b7c42f006554a5dde480",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "4fc7a476-6ef6-47a8-8cee-25993261ce6a",
+ "source_system": "documented-relations-repair",
+ "external_id": "72c13e83-e8dd-465d-99a9-eb0ccaa4fd0b:c0a78e45-ebaa-590e-847f-8ba68e4b2fbe:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "9c2398a0-e3ae-4225-b198-2eec9674a37f",
+ "geo_location_id": "c0a78e45-ebaa-590e-847f-8ba68e4b2fbe",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "c0a78e45-ebaa-590e-847f-8ba68e4b2fbe",
+ "name": "Tete",
+ "location_type": "province",
+ "source_code": "05",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "72c13e83-e8dd-465d-99a9-eb0ccaa4fd0b",
+ "source_quote": "Corredor entre Moatize, na província de Tete, e Macuse, no distrito de Nicoadala, província da Zambézia, incluindo Mutarara, Mopeia e Quelimane.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A11",
+ "source_project_id": "9c2398a0-e3ae-4225-b198-2eec9674a37f",
+ "project_id": "54f80879-0fcc-4bc9-9612-c6fcefd26e69",
+ "dossier_id": "cb125f84-6f75-48e5-a0de-2f5e6bd537ed",
+ "content_sha256": "736fc41d941740f41697c579ffe6c4208d45005d7177b7c42f006554a5dde480",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "d3617041-e1a5-4c76-9c56-e16bc806bde8",
+ "source_system": "documented-relations-repair",
+ "external_id": "72c13e83-e8dd-465d-99a9-eb0ccaa4fd0b:c20efcce-8af8-588d-84b2-b4b138b6e066:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "9c2398a0-e3ae-4225-b198-2eec9674a37f",
+ "geo_location_id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "name": "Zambezia",
+ "location_type": "province",
+ "source_code": "04",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "72c13e83-e8dd-465d-99a9-eb0ccaa4fd0b",
+ "source_quote": "Corredor entre Moatize, na província de Tete, e Macuse, no distrito de Nicoadala, província da Zambézia, incluindo Mutarara, Mopeia e Quelimane.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A12",
+ "source_project_id": "59f9d973-4974-4d54-8f25-2af5188801df",
+ "project_id": "6d3dce0b-4b37-4071-99f1-a3a766da86b7",
+ "dossier_id": "71b96599-09c2-4809-b98f-acbf0c2b6f38",
+ "content_sha256": "9dbdb468b8644e07fabdc943ecde2f11ea561d5174c00559228ed29b2a29b1fe",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "0bfaeb27-2850-4f5a-b61a-4707e78d178c",
+ "source_system": "documented-relations-repair",
+ "external_id": "a023d6b2-1fa2-4fe7-9709-f93ae1f10e99:c20efcce-8af8-588d-84b2-b4b138b6e066:primary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "59f9d973-4974-4d54-8f25-2af5188801df",
+ "geo_location_id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "role": "primary"
+ },
+ "territory": {
+ "id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "name": "Zambezia",
+ "location_type": "province",
+ "source_code": "04",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "a023d6b2-1fa2-4fe7-9709-f93ae1f10e99",
+ "source_quote": "Província da Zambézia, com incidência em zonas rurais, no rio Licungo, na Circular de Mocuba e em comunidades e ecossistemas costeiros.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A13",
+ "source_project_id": "819b8981-55e3-471a-b95d-7e9047c3dcdc",
+ "project_id": "d1078baf-5ffa-42f8-8bd4-3adcc0e43cee",
+ "dossier_id": "5ce2d415-1c84-4625-a4cd-0f6738454318",
+ "content_sha256": "7a62afdda8e2c3fcc47b1c9032359906ff75dff9b5d56c71ba7d88781a8f8620",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "f9c911c4-3a79-415d-989f-d4b724153f81",
+ "source_system": "documented-relations-repair",
+ "external_id": "bb15487f-1617-49e6-86b7-d617812b658b:9e42dac8-fd9b-523f-bf59-71a7d3aa0fb8:primary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "819b8981-55e3-471a-b95d-7e9047c3dcdc",
+ "geo_location_id": "9e42dac8-fd9b-523f-bf59-71a7d3aa0fb8",
+ "role": "primary"
+ },
+ "territory": {
+ "id": "9e42dac8-fd9b-523f-bf59-71a7d3aa0fb8",
+ "name": "Inhambane",
+ "location_type": "province",
+ "source_code": "08",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "bb15487f-1617-49e6-86b7-d617812b658b",
+ "source_quote": "Corredor turístico Vilanculos–Inhassoro–Bazaruto, província de Inhambane, incluindo áreas costeiras e ilhas associadas.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A14",
+ "source_project_id": "6307d00f-0dbd-4169-be0a-09d813f8007e",
+ "project_id": "8652f52c-b84e-4b8b-935f-ba07622f95d6",
+ "dossier_id": "88111fb4-ab20-4393-bd1b-3a1694fb4ac4",
+ "content_sha256": "930836392126133499fa69313a4718ce2ec1f6c8f0839c184e9b5cc229460d1c",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "709c9758-a502-438d-9314-7d7a7fb972f0",
+ "source_system": "documented-relations-repair",
+ "external_id": "6d973bb4-ab8a-49bc-92ed-286ed5b96fc4:8ed9aa8a-8815-5863-97ec-494e40a7ea81:primary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "6307d00f-0dbd-4169-be0a-09d813f8007e",
+ "geo_location_id": "8ed9aa8a-8815-5863-97ec-494e40a7ea81",
+ "role": "primary"
+ },
+ "territory": {
+ "id": "8ed9aa8a-8815-5863-97ec-494e40a7ea81",
+ "name": "Gaza",
+ "location_type": "province",
+ "source_code": "09",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "6d973bb4-ab8a-49bc-92ed-286ed5b96fc4",
+ "source_quote": "Vale do Limpopo, província de Gaza: Chókwè, Xai-Xai, Guijá, Chongoene, Chibuto, Limpopo e Bilene.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A15",
+ "source_project_id": "97f15c0a-8c44-4b41-b96b-389da1e77f29",
+ "project_id": "2c266cdf-2278-4101-9147-ddb809c51ff4",
+ "dossier_id": "88e37c63-e785-446f-9074-84b000bffa59",
+ "content_sha256": "d19d27451296b9816351e2d340f2aaff9fabf9732fb580d179e1c69ceb9fc512",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "9f781744-f05d-4f8e-9c7c-69e9414acbb8",
+ "source_system": "documented-relations-repair",
+ "external_id": "1468b8d2-1b08-4c84-8000-ece7662edbf6:bfde2651-2b46-5d9c-a500-733fa55a8c5c:primary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "97f15c0a-8c44-4b41-b96b-389da1e77f29",
+ "geo_location_id": "bfde2651-2b46-5d9c-a500-733fa55a8c5c",
+ "role": "primary"
+ },
+ "territory": {
+ "id": "bfde2651-2b46-5d9c-a500-733fa55a8c5c",
+ "name": "Maputo Província",
+ "location_type": "province",
+ "source_code": "10",
+ "parent_id": "d7c64b9b-72b0-5f48-9b95-32b641d19f72",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Província explicitamente identificada na localização do dossier autorizado",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "1468b8d2-1b08-4c84-8000-ece7662edbf6",
+ "source_quote": "Bacia Hidrográfica do Rio Maputo, província de Maputo, com incidência nos distritos de Boane, Moamba e Namaacha e ligação às bacias do Maputo e Incomáti.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A15",
+ "source_project_id": "97f15c0a-8c44-4b41-b96b-389da1e77f29",
+ "project_id": "2c266cdf-2278-4101-9147-ddb809c51ff4",
+ "dossier_id": "88e37c63-e785-446f-9074-84b000bffa59",
+ "content_sha256": "d19d27451296b9816351e2d340f2aaff9fabf9732fb580d179e1c69ceb9fc512",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "1199d360-f133-4b38-b950-ea8e925ca170",
+ "source_system": "documented-relations-repair",
+ "external_id": "1468b8d2-1b08-4c84-8000-ece7662edbf6:c86c06b8-1f8a-561c-b92b-58a53894f865:impact",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "97f15c0a-8c44-4b41-b96b-389da1e77f29",
+ "geo_location_id": "c86c06b8-1f8a-561c-b92b-58a53894f865",
+ "role": "impact"
+ },
+ "territory": {
+ "id": "c86c06b8-1f8a-561c-b92b-58a53894f865",
+ "name": "BOANE",
+ "location_type": "district",
+ "source_code": "02",
+ "parent_id": "bfde2651-2b46-5d9c-a500-733fa55a8c5c",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Distrito explicitamente identificado na fonte; sem inferir posto, localidade ou coordenadas.",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "1468b8d2-1b08-4c84-8000-ece7662edbf6",
+ "source_quote": "Bacia Hidrográfica do Rio Maputo, província de Maputo, com incidência nos distritos de Boane, Moamba e Namaacha e ligação às bacias do Maputo e Incomáti.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A15",
+ "source_project_id": "97f15c0a-8c44-4b41-b96b-389da1e77f29",
+ "project_id": "2c266cdf-2278-4101-9147-ddb809c51ff4",
+ "dossier_id": "88e37c63-e785-446f-9074-84b000bffa59",
+ "content_sha256": "d19d27451296b9816351e2d340f2aaff9fabf9732fb580d179e1c69ceb9fc512",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "c3fde0b9-3c41-47ae-8aca-19ba35d13e73",
+ "source_system": "documented-relations-repair",
+ "external_id": "1468b8d2-1b08-4c84-8000-ece7662edbf6:a861e246-0b0f-50aa-94eb-4dc3fa7d8c2b:impact",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "97f15c0a-8c44-4b41-b96b-389da1e77f29",
+ "geo_location_id": "a861e246-0b0f-50aa-94eb-4dc3fa7d8c2b",
+ "role": "impact"
+ },
+ "territory": {
+ "id": "a861e246-0b0f-50aa-94eb-4dc3fa7d8c2b",
+ "name": "MOAMBA",
+ "location_type": "district",
+ "source_code": "07",
+ "parent_id": "bfde2651-2b46-5d9c-a500-733fa55a8c5c",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Distrito explicitamente identificado na fonte; sem inferir posto, localidade ou coordenadas.",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "1468b8d2-1b08-4c84-8000-ece7662edbf6",
+ "source_quote": "Bacia Hidrográfica do Rio Maputo, província de Maputo, com incidência nos distritos de Boane, Moamba e Namaacha e ligação às bacias do Maputo e Incomáti.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A15",
+ "source_project_id": "97f15c0a-8c44-4b41-b96b-389da1e77f29",
+ "project_id": "2c266cdf-2278-4101-9147-ddb809c51ff4",
+ "dossier_id": "88e37c63-e785-446f-9074-84b000bffa59",
+ "content_sha256": "d19d27451296b9816351e2d340f2aaff9fabf9732fb580d179e1c69ceb9fc512",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "a302c254-7743-48bb-858e-9e3563df5b15",
+ "source_system": "documented-relations-repair",
+ "external_id": "1468b8d2-1b08-4c84-8000-ece7662edbf6:ce1dc61a-a567-5127-af4c-f6b714e77ebf:impact",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "97f15c0a-8c44-4b41-b96b-389da1e77f29",
+ "geo_location_id": "ce1dc61a-a567-5127-af4c-f6b714e77ebf",
+ "role": "impact"
+ },
+ "territory": {
+ "id": "ce1dc61a-a567-5127-af4c-f6b714e77ebf",
+ "name": "NAMAACHA",
+ "location_type": "district",
+ "source_code": "08",
+ "parent_id": "bfde2651-2b46-5d9c-a500-733fa55a8c5c",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Distrito explicitamente identificado na fonte; sem inferir posto, localidade ou coordenadas.",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "1468b8d2-1b08-4c84-8000-ece7662edbf6",
+ "source_quote": "Bacia Hidrográfica do Rio Maputo, província de Maputo, com incidência nos distritos de Boane, Moamba e Namaacha e ligação às bacias do Maputo e Incomáti.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ },
+ {
+ "code": "A11",
+ "source_project_id": "9c2398a0-e3ae-4225-b198-2eec9674a37f",
+ "project_id": "54f80879-0fcc-4bc9-9612-c6fcefd26e69",
+ "dossier_id": "cb125f84-6f75-48e5-a0de-2f5e6bd537ed",
+ "content_sha256": "736fc41d941740f41697c579ffe6c4208d45005d7177b7c42f006554a5dde480",
+ "source_sha256": "4919cd8aae6230e576947b38e5ff839b2661166fb2a8598bea1d662f15bd170a",
+ "original_relation": {
+ "id": "10117428-e3f9-4eff-9fe7-c6f362e3940b",
+ "source_system": "documented-relations-repair",
+ "external_id": "72c13e83-e8dd-465d-99a9-eb0ccaa4fd0b:c608862a-4272-5f60-8ade-f08c7ef6e5a0:secondary",
+ "version_no": 1,
+ "data_classification": "public",
+ "correlation_id": null,
+ "created_at": "2026-10-07 12:59:36.558503+00",
+ "updated_at": "2026-10-07 12:59:36.558503+00",
+ "deleted_at": null,
+ "project_id": "9c2398a0-e3ae-4225-b198-2eec9674a37f",
+ "geo_location_id": "c608862a-4272-5f60-8ade-f08c7ef6e5a0",
+ "role": "secondary"
+ },
+ "territory": {
+ "id": "c608862a-4272-5f60-8ade-f08c7ef6e5a0",
+ "name": "NICOADALA",
+ "location_type": "district",
+ "source_code": "16",
+ "parent_id": "c20efcce-8af8-588d-84b2-b4b138b6e066",
+ "data_classification": "public",
+ "deleted_at": null
+ },
+ "evidence": {
+ "reason": "Distrito explicitamente identificado na fonte; sem inferir posto, localidade ou coordenadas.",
+ "plan_hash": "c8e8c2fb962058be5d8c0518343a97f6a9524cf40153c1888cd382631b95736b",
+ "dossier_id": "72c13e83-e8dd-465d-99a9-eb0ccaa4fd0b",
+ "source_quote": "Corredor entre Moatize, na província de Tete, e Macuse, no distrito de Nicoadala, província da Zambézia, incluindo Mutarara, Mopeia e Quelimane.",
+ "source_reference": "upgrade do portal de investimentos v4 programacao.docx — 6.1 / 6.6"
+ }
+ }
+ ]
+}
diff --git a/docs/investmoz/unification/traceability-and-manual.md b/docs/investmoz/unification/traceability-and-manual.md
index 5dd06ff3..305a427f 100644
--- a/docs/investmoz/unification/traceability-and-manual.md
+++ b/docs/investmoz/unification/traceability-and-manual.md
@@ -1,5 +1,17 @@
# Rastreabilidade, utilização e formação
+## Projectos âncora — integração executável em QA, 23/10/2026
+
+Reconciliado o saldo de `6985f82e` com as provas territoriais de 7 de Outubro e os recibos de reposição. A leitura autenticada da homologação, com o papel da aplicação e transacção apenas de leitura, confirmou **29 fichas publicadas, 13 relações de clusters e zero ligações em `project_locations`**. As cinco tabelas comparadas não usam RLS. Os projectos transportados têm identificadores diferentes dos originais e perderam as 28 ligações territoriais e os respectivos metadados de citação; não desapareceram as 29 fichas. A reposição de visibilidade anterior não abrangia estas relações. A comparação delimita a omissão no transporte; não identifica por si só o instante em que ocorreu.
+
+O [manifesto das 28 relações aceites](approved-anchor-territories-20261023.json) conserva identidades históricas, fontes, citações e papéis primary/secondary/impact, mapeando os projectos e dossiers actuais por identidade documental verificada. A ferramenta `tools/restore-approved-anchor-territories.php` confere hashes, versões, território e prévia; recusa conflitos e exemplares arquivados/restritos; preserva metadados concorrentes, guarda estado anterior e produz auditoria. Não publica fichas nem cria ofertas. Em QA foram repostas 28 relações de 13 projectos; a repetição foi demonstrada sem duplicação. A01/A02 continuam sem implantação individual inventada; Norte da Zambézia conserva o papel de impacto parcial.
+
+Incrementos: pesquisa explícita pelo sector documental em conjunto com a localização; entrada directa da ficha pública para preparar uma ideia, mesmo sem oportunidade publicada; origem `portfolio:` guardada no dossier e no snapshot/relatório do simulador. A cobertura documental não é atribuída como implantação. A localização explicitamente escolhida na pesquisa acompanha a entrada; uma localização já guardada conserva-se, com divergência explicada. Títulos e dados deliberadamente editados mantêm-se na comparação existente. A retoma autenticada da manifestação conserva a mesma ficha e os filtros e não cria pedidos por GET. A preparação iniciada pela manifestação usa a associação já existente ao dossier, com controlo de proprietário e versões; não submete o pedido.
+
+Provas dirigidas: `InvestmentAnchorIntegrationTest` (4 casos, 116 asserções) e `anchor-integration.test.mjs` (2 casos); ver [recibo de QA e reconciliação](anchor-integration-receipt-20261023.json). Mantidos os percursos já aceites de carteira → oportunidade associada → dossier/simulador, complementos `d8224ba8`, consumidores `55136b44` e tratamento `8036b9b0`/recibo `cdf8fcfb`. Nenhuma nova impressão de PDF, prova Word/ZIP ou ronda dos fechos aceites. Estatísticas e IA permanecem adiadas.
+
+Estado desta passagem: código e reposição demonstrados em QA; **a entrega na homologação e a aplicação das 28 relações no destino ainda não estão declaradas concluídas**. O saldo deste recorte é finito: instalar o incremento pelo Git, aplicar a reposição exacta após backup/restauro autenticado e conferir apenas esse delta. O backup já preparado do destino restaurou 174 tabelas iguais numa base isolada sem rede e verificou 369 ficheiros. A avaliação final de navegação e apresentação pela Tempo continua distinta deste fecho técnico.
+
## Oportunidade em tratamento — entregue na homologação em 8036b9b0, 23/10/2026
Concluída a disponibilização autorizada da candidata **`1afdfee8`**, incluindo a correcção delimitada do relatório **`2856240c`**, na revisão instalada **`8036b9b071229dbf7e85ea748db70abcbeefc379`**. Integração normal por fast-forward desde `55136b44`, sem force e sem alterações concorrentes em `main` na conferência prévia. [Recibo de instalação e delta](treatment-scope-installation-receipt-20261023.json).
diff --git a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv
index 5185a23d..d94bb741 100644
--- a/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv
+++ b/docs/investmoz/v2/auditoria-portal/matriz-requisitos.csv
@@ -4699,11 +4699,9 @@ AUD-REL-01,Preservar relações territoriais e citar por associação,"Pedido di
[Executável 82dab3719ffc] P3 staging privado completo; P4 nominal destino real 27 refs/25 territórios, zero geometrias. Pré-condições fontes conferidas; pacote para decisão, não aplicado. Reversão após uso só manifesto/build, backend e dados retidos. Adaptador ensaiado só em clone: rollback/recuperação após commit e repetição sem duplicações; aplicação 56 fontes inalterada. Acesso público e diferenças visuais/login continuam abertos. Saldo remoto delimitado 4–7 h; sem alterações remotas.
[Executável 312965f2c653] P3 staging privado completo; P4 nominal destino real 27 refs/25 territórios, zero geometrias. Pré-condições fontes conferidas; pacote para decisão, não aplicado. Reversão após uso só manifesto/build, backend e dados retidos. Adaptador ensaiado só em clone: rollback/recuperação após commit e repetição sem duplicações; aplicação 56 fontes inalterada. Acesso público e diferenças visuais/login continuam abertos. Saldo remoto delimitado 4–7 h; sem alterações remotas.
[Homologação 312965f2c653 executada] Autorização Tempo; 30 fichas privadas/30 locais/31 suportes/11 relações/2 originais e 2 definições internas, 233 caminhos conferidos. Dados anteriores/permissões preservados; zero publicação/migrations/geometrias/P7. Saldo delimitado de execução concluído. Dossier legítimo, oito lacunas e questões de autenticação/visual separadas. RECIBO-EXECUCAO-312965.json. | 22/10/2026 — selectores especializados em QA: opções de cadastros públicos independentes das oportunidades; território principal documentado ou vínculos já publicados; cadeia pelo cluster e actividade como classificação pública. Vazio explicado; zero correspondências mantém ficha pública existente. Cabo Delgado/Nampula/nacional, selecção/limpeza/ficha/regresso/recarregamento; fixtures exclusivamente QA. CatalogueSelectorReferencesTest: 3 testes, 27 verificações; tipos/build passaram. Homologação já oferece Balama/Montepuez; a base local tinha dados distintos. Sem publicação/activação ou integração nesta execução. Manual: secção Selectores especializados do catálogo; provas outputs/catalogue-selectors-20261022.",território,12/10/2026 — reconciliação e HTTP; nova inspeção visual bloqueada,,,Pontes de rastreabilidade em falta; não inferir pares oportunidade–projeto/cluster,Acervo aceite; recuperar citação de cada par,InvestmentRelationshipRepair; InvestmentTerritorialTraceability,Leitura ativa e suite territorial; confirmação histórica V2,Não demonstrado individualmente; localizar critério e executar em QA.,,,,"2–8 h de reconciliação/ensaio por consumidor agrupado, pressupondo dados sintéticos/perfis preparados. Alteração: estimar após reprodução concreta; variante integral pode exceder esta faixa.",,,
-AUD-REL-02,Correspondência das seis oportunidades com âncoras/clusters,"Pedido direto 09/10/2026, auditoria §1–4; fontes específicas descritas em relatorio-executivo.md Pedido expresso da Tempo, 23/10/2026, nesta retoma: corrigir integração de complementos no percurso actual, com identidade, cadeia de valor, localização e relações documentadas.",cartografia/relações,/management/opportunities/{id}/context,"InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/reused-evidence-integrity.json: 35 recibos anteriores com hashes correspondentes; o âmbito de cada recibo permanece limitado ao critério ensaiado. outputs/investmoz-audit-current-20261012/http-promoter.json; http-validator.json; http-publisher.json; http-manager.json.,Dependente de decisão concreta da Tempo,Os pares das seis oportunidades legadas com projetos/âncoras/clusters continuam indeterminados. Indicar pares com fundamento documental; não bloquear as oportunidades independentes.,"QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada. Os pares das seis oportunidades legadas com projetos/âncoras/clusters continuam indeterminados. Indicar pares com fundamento documental; não bloquear as oportunidades independentes.",AUD-REL-02: Somente pares explicitamente identificados pelo responsável/documento; sem duplicar relações,P1,AUD-REL-02: Relatórios históricos mantidos; estado ativo apurado por leitura nesta auditoria,AUD-REL-02,1,"[{""id"":""AUD-REL-02"",""pedido"":""Correspondência das seis oportunidades com âncoras/clusters"",""fontes"":[""Pedido direto 09/10/2026, auditoria §1–4; fontes específicas descritas em relatorio-executivo.md""],""aceitacao"":""Somente pares explicitamente identificados pelo responsável/documento; sem duplicar relações"",""estado"":""dependente de decisão concreta"",""variantes"":""Relatórios históricos mantidos; estado ativo apurado por leitura nesta auditoria"",""modulo"":""cartografia/relações""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,dependente de decisão concreta,geo_locations: 1990; geo_geometries: 0; project_locations: 28; cluster_projects: 13; opportunity_projects: 0; opportunity_clusters: 0,"Decisão concreta isolada explicitada; não bloqueia as frentes independentes já autorizadas.
+AUD-REL-02,Correspondência das seis oportunidades com âncoras/clusters,"Pedido direto 09/10/2026, auditoria §1–4; fontes específicas descritas em relatorio-executivo.md Pedido expresso da Tempo, 23/10/2026, nesta retoma: corrigir integração de complementos no percurso actual, com identidade, cadeia de valor, localização e relações documentadas.",cartografia/relações,/management/opportunities/{id}/context,"InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Ativo investemoz:5432, 295 tabelas, COUNTRY02/030000/040000 instalados; seis categorias e administração habilitadas. Leitura atual não demonstra esta cláusula individual. Legado, percurso integrado, modulares/ofertas e notificações desabilitados.",outputs/investmoz-audit-current-20261012/reused-evidence-integrity.json: 35 recibos anteriores com hashes correspondentes; o âmbito de cada recibo permanece limitado ao critério ensaiado. outputs/investmoz-audit-current-20261012/http-promoter.json; http-validator.json; http-publisher.json; http-manager.json.,Dependente de decisão concreta da Tempo,Os pares das seis oportunidades legadas com projetos/âncoras/clusters continuam indeterminados. Indicar pares com fundamento documental; não bloquear as oportunidades independentes.,"QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada. Os pares das seis oportunidades legadas com projetos/âncoras/clusters continuam indeterminados. Indicar pares com fundamento documental; não bloquear as oportunidades independentes.",AUD-REL-02: Somente pares explicitamente identificados pelo responsável/documento; sem duplicar relações,P1,AUD-REL-02: Relatórios históricos mantidos; estado ativo apurado por leitura nesta auditoria,AUD-REL-02,1,"[{""id"":""AUD-REL-02"",""pedido"":""Correspondência das seis oportunidades com âncoras/clusters"",""fontes"":[""Pedido direto 09/10/2026, auditoria §1–4; fontes específicas descritas em relatorio-executivo.md""],""aceitacao"":""Somente pares explicitamente identificados pelo responsável/documento; sem duplicar relações"",""estado"":""dependente de decisão concreta"",""variantes"":""Relatórios históricos mantidos; estado ativo apurado por leitura nesta auditoria"",""modulo"":""cartografia/relações""}]",Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Não demonstrado individualmente; localizar critério e executar em QA.,Texto exatamente equivalente no mesmo módulo; sem fusão semântica aproximada,dependente de decisão concreta,geo_locations: 1990; geo_geometries: 0; project_locations: 28; cluster_projects: 13; opportunity_projects: 0; opportunity_clusters: 0,"23/10/2026: anchor integration executable in isolated QA; 4 tests/116 assertions + 2 frontend tests; 28 accepted territorial links recovered in QA, 29 real published fiches preserved. Receipt docs/investmoz/unification/anchor-integration-receipt-20261023.json. Homologation still 8036b9b0 until Git installation and exact 28-link recovery; no accepted proofs repeated; statistics/AI deferred. | Decisão concreta isolada explicitada; não bloqueia as frentes independentes já autorizadas.
-[RECONCILIACAO-43-20261019] 23: 1921 referências e zero geometrias no destino. Reconciliar geometrias/fontes/classificação existentes em QA e consumidores abertos; corrigir bug de2. Não transformar divergência de contagens em importação.","Os pares das seis oportunidades legadas com projetos/âncoras/clusters continuam indeterminados. Indicar pares com fundamento documental; não bloquear as oportunidades independentes.
-
-[UTILIZACAO-HOMOLOGACAO-20261019] 23: Implementação parcial + dados — Consumidores cartográficos restantes e correspondências geográficas por item; diferença de contagens não identifica registos em falta. Delta de complementos preparado/verificado em QA; conferência visual e instalação no destino ainda não realizadas. Relações sem oferta identificada permanecem necessidades, sem presumir inexistência no acervo. Cobertura transversal e restantes pendências desta linha mantêm-se. Actualização visual 23/10/2026: supera apenas a pendência visual dos complementos no recorte documentado. Não demonstra contextos específicos de várias oportunidades em zonas/parques, Terra/DUAT, Balcão ou manifestação. Sem disponibilização no destino nem fecho global. | **Incluído por pedido expresso da Tempo nesta passagem.** Verificar pesquisa combinada por sector e localização, abertura pela identidade existente, continuidade para manifestação de interesse e preparação do investimento, e recuperação no mesmo dossier com fontes/associações documentadas. A reposição/consulta anteriormente aceite de fichas e relações não demonstra, por si só, este requisito completo. **Estado: por analisar; não se presume implementação nem falha.** Registado em `AUD-REL-02` e articulado com `AUD-LEG-06`, sem nova matriz/backlog. Este recorte permanece no saldo antes da avaliação final pela Tempo; Estatísticas e IA continuam adiadas. | [Analise corrente 23/10/2026] Recorte ancora analisado: duas lacunas de implementacao (filtro sectorial combinado com localizacao e ideia directa a partir de ancora sem oferta); uma reconciliacao de dados/ambiente e uma prova dirigida de interesse/login. Quinze fichas documentais QA mantem texto de sector/localizacao/regiao, sem correspondencias territoriais canonicas nem oferta publica directa nesse clone; ficha SYNTHETIC QA separada. Nao inferir perda na homologacao. Preservar recibo de 29 fichas e continuidade via oportunidade ja aceite. Ver inicio do manual para escopo, fontes e criterios; nenhuma implementacao de ancoras nesta passagem.","InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada.",Os pares das seis oportunidades legadas com projetos/âncoras/clusters continuam indeterminados. Indicar pares com fundamento documental; não bloquear as oportunidades independentes.,Decisão Tempo + trabalho independente paralelo,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: território. Esforço de código adicional só após lacuna reproduzida.,"outputs/investmoz-audit-current-20261012/reused-evidence-integrity.json: 35 recibos anteriores com hashes correspondentes; o âmbito de cada recibo permanece limitado ao critério ensaiado. outputs/investmoz-audit-current-20261012/http-promoter.json; http-validator.json; http-publisher.json; http-manager.json. | Homologação teste-investidor 19/10/2026: Cartografia e consumidores territoriais restantes=Não demonstrado. Saldo derivado e limites em outputs/investmoz-disponibilizacao-integral-20261019/SALDO-E-ACTUALIZACAO-CONSOLIDADA.md. Não substitui estado/provas do activo; trecho documental encerrado, vínculo dossier aberto. | Proposta integral fdcb31f1b5b9: aplicação activa local completa + R2/DOC01/destino reconciliados; schema/build/recuperação de contexto e reversão de apresentação ensaiados no clone isolado. Não instalado remotamente. Inc. QA territoriais/Inhambane/programas separados. Limites e decisões em outputs/investmoz-disponibilizacao-integral-20261019/PROPOSTA-INTEGRAL-PARA-DECISAO.md. | Execução autorizada fdcb31f1b5b9 concluída em teste-investidor: Cartografia e consumidores territoriais restantes=Não demonstrado. 1080 hashes iguais, schema171/88, custódia/scan/recuperação reais. Sem publicação ou papéis novos. Vínculo dossier legítimo pendente; incrementos QA separados. Limites em outputs/investmoz-disponibilizacao-integral-20261019/RESULTADO-DISPONIBILIZACAO-INTEGRAL.md; não encerra critérios globais não demonstrados.
+[RECONCILIACAO-43-20261019] 23: 1921 referências e zero geometrias no destino. Reconciliar geometrias/fontes/classificação existentes em QA e consumidores abertos; corrigir bug de2. Não transformar divergência de contagens em importação.",Anchor slice: Git installation; authenticated exact 28-link recovery after verified backup/restore; installed delta. Tempo final navigation/presentation review. Previous accepted closures preserved.,"InvestmentGeography, campos TerritoryFields/ProvinceSelect, geo_locations/geo_geometries e importador autenticado","QA408/581INE; ativo0geometrias;173correspondências por nome/edição/pai, Mandie ambíguo. Publicação é ação separada.",Os pares das seis oportunidades legadas com projetos/âncoras/clusters continuam indeterminados. Indicar pares com fundamento documental; não bloquear as oportunidades independentes.,Decisão Tempo + trabalho independente paralelo,Estimativa partilhada no lote correspondente de visao-consolidada-modulos.md; não somar por linha/cláusula/campo. Grupo: território. Esforço de código adicional só após lacuna reproduzida.,"23/10/2026: anchor integration executable in isolated QA; 4 tests/116 assertions + 2 frontend tests; 28 accepted territorial links recovered in QA, 29 real published fiches preserved. Receipt docs/investmoz/unification/anchor-integration-receipt-20261023.json. Homologation still 8036b9b0 until Git installation and exact 28-link recovery; no accepted proofs repeated; statistics/AI deferred. | outputs/investmoz-audit-current-20261012/reused-evidence-integrity.json: 35 recibos anteriores com hashes correspondentes; o âmbito de cada recibo permanece limitado ao critério ensaiado. outputs/investmoz-audit-current-20261012/http-promoter.json; http-validator.json; http-publisher.json; http-manager.json. | Homologação teste-investidor 19/10/2026: Cartografia e consumidores territoriais restantes=Não demonstrado. Saldo derivado e limites em outputs/investmoz-disponibilizacao-integral-20261019/SALDO-E-ACTUALIZACAO-CONSOLIDADA.md. Não substitui estado/provas do activo; trecho documental encerrado, vínculo dossier aberto. | Proposta integral fdcb31f1b5b9: aplicação activa local completa + R2/DOC01/destino reconciliados; schema/build/recuperação de contexto e reversão de apresentação ensaiados no clone isolado. Não instalado remotamente. Inc. QA territoriais/Inhambane/programas separados. Limites e decisões em outputs/investmoz-disponibilizacao-integral-20261019/PROPOSTA-INTEGRAL-PARA-DECISAO.md. | Execução autorizada fdcb31f1b5b9 concluída em teste-investidor: Cartografia e consumidores territoriais restantes=Não demonstrado. 1080 hashes iguais, schema171/88, custódia/scan/recuperação reais. Sem publicação ou papéis novos. Vínculo dossier legítimo pendente; incrementos QA separados. Limites em outputs/investmoz-disponibilizacao-integral-20261019/RESULTADO-DISPONIBILIZACAO-INTEGRAL.md; não encerra critérios globais não demonstrados.
[UTILIZACAO-HOMOLOGACAO-20261019] Leitura nominal de contas/recursos no destino; saldo18/10; prévia29 sem escrita; comparação de hashes QA separados. outputs/investmoz-disponibilizacao-integral-20261019/UTILIZACAO-EFECTIVA-HOMOLOGACAO.md
@@ -10518,11 +10516,9 @@ AUD-LEG-05,"Fonte única associada a setores, territórios e etapas com fundamen
[RECONCILIACAO-43-20261019] Código e critérios confrontados com leitura READ ONLY fresca; PROVA-RECONCILIACAO-43-LEITURA.json, RECONCILIACAO-43-QA-FONTES.json, RECONCILIACAO-43-SCHEMA-QA.json. Não encerra critério funcional por inventário.
[PLANO-P1-P6-20261019] Plano Tempo: 27–46 h disponibilização; P7 e desenvolvimento separados. Inclusão 36–39 expressa para decisão; sem publicação automática. Revisão de proposta d87970e701f0. Roteiro no manual existente; não encerra critério por instalação.",documentos e legado,15/10/2026 — fecho do piloto ativo e preparação por leitura dos restantes setores; sem novos testes funcionais.,,,"Mesma biblioteca/versão/imagem reutilizada. Turismo editorial sem geometrias inferidas; relações territoriais e por etapa ainda exigem fundamento concreto. | Histórico anterior: Relações territoriais concretas e ampliação por etapa/setor ainda por fundamentar. Fonte única no piloto, sem criar oportunidades ou geometrias pelo artigo.",Biblioteca/documentos existentes; Balcão+09/190000 para dossier. Expansão cartográfica exige correspondências fundamentadas. C37/A-B/SLA/perfis e ativação mantêm âmbito próprio.,"Documento único6 e imagem5; três links com fundamento: tema, thumbnail e apoio editorialS01. Relações de oportunidades pelo setor já cadastrado; zero oportunidade ou geometria criada pelo artigo.","[Interface legado QA 10/10/2026] Chromium instalado, contextos isolados, desktop 1440 px / móvel 390 px: fotografia/fontes/paleta, pesquisa hit/miss, Enter/foco de 3 px, links carteira/zonas/biblioteca/oportunidade. Promotor QA21: login→MFA→dossier→fonte→retorno→logout→novo contexto/MFA→recuperação/F5→associação repetida. Conta23:403 e artigo público sem título privado; anónimo sem contexto privado. UI observada; referência/evento únicos e originais/hash/scan confirmados em leitura QA. legacy-content-browser-qa.json; legacy-content-browser-persistence-qa.json; legado-piloto-qa.md. | Evidência anterior preservada: legado-piloto-qa.md; legacy-content-http-qa.json: recursos6/5 públicos, hashes verificados, pesquisa, login/MFA21, criação/continuação, logout/nova sessão, recuperação, replay único e isolamento. Interface não observada. | [Setores QA após C71 10/10/2026] 22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos/recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia200. Chromium desktop:16 artigos, pesquisa/imagens, Energia e Mineração distintas, C72 título preservado; QA21 criou4 dossiers, retorno, logout/novaMFA/F5/replay; QA23 negado403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP/Chromium, uma referência/evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence}-qa.json; legacy-financial-origin-20261010/proof.json. C37/QA18,A/B,móvel/acessibilidade/cobertura integral não encerrados.","GET públicos e escritas autenticadas no servidor18097, alvo real55441 confirmado; publicação separada do importador. | [Setores QA após C71 10/10/2026] 22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos/recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia200. Chromium desktop:16 artigos, pesquisa/imagens, Energia e Mineração distintas, C72 título preservado; QA21 criou4 dossiers, retorno, logout/novaMFA/F5/replay; QA23 negado403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP/Chromium, uma referência/evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence}-qa.json; legacy-financial-origin-20261010/proof.json. C37/QA18,A/B,móvel/acessibilidade/cobertura integral não encerrados.",,,"Fecho exclusivo do piloto agronegócio; não cobre todo o acervo, versões, URLs, anexos ou setores. Mercado Financeiro vazio continua separado. | 19/10/2026 — Inhambane v1, lote QA separado a2b47f486332c78926202eb462c5238fac15ffc8afb2fe391e47b091541e2058. Fonte32c6ab160c50… comparada com anterior9f628cd57eb8…; 39 itens+5 condições reconciliados em30 rascunhos privados/30 locais,2 originais privados com scan real ClamAV. Repetição sem duplicação, fontes/intervalos/agregados preservados, nenhum total financeiro do lote. Backend de recuperação e confidencialidade demonstrado; login real/edição visual/publicação/percurso positivo destas fichas pendentes. Lacunas concretas: dados do promotor/contacto/taxonomia/local, proveniência documental no snapshot do dossier e reutilização biblioteca→anexo canónico. Sem novos papéis, migrations, alteração activa ou incorporação na HML01. outputs/investmoz-inhambane-v1-QA-20261019/RELATORIO-QA.md. Não encerra requisito global.","2–8 h de reconciliação/ensaio por consumidor agrupado, pressupondo dados sintéticos/perfis preparados. Alteração: estimar após reprodução concreta; variante integral pode exceder esta faixa.",,,
-AUD-LEG-06,"Preservar contexto ao entrar/regressar ao percurso, URLs existentes e correspondências de migração","Pedido direto do responsável,10/10/2026, integração do legado emQA §6; https://investemoz.tempo.co.mz/; legado-piloto-qa.md Pedido expresso da Tempo, 23/10/2026, nesta retoma: corrigir integração de complementos no percurso actual, com identidade, cadeia de valor, localização e relações documentadas.",biblioteca / conteúdo público / percurso do investidor,/explorar/agronegocio; /agronegocio; /documentos/6; /investimentos/a-partir-de/agronegocio; /investimentos/{id}/conteudos,"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Disponibilizado em 15/10/2026, setores-fintech-QA-d5b4dc354265 DOC01: 16 fontes e compilação; sete entradas setoriais e especialização Fintech no dossier; três artigos publicados (recursos reais 27/28/29), imagem 24 reutilizada por identidade/hash. Flags existentes preservadas; sem migrations/categorias novas. B e COUNTRY02 preservados. | 22/10/2026 — disponibilizado por autorização Tempo: revisão servida042ffbde (inclui a76369eb/a1fbda06/064296e1 e correcção dirigida da recuperação legada). Percurso habilitado na homologação, versão private-investment-preparation-2026-v1; main ancestral preservado, sem conflitos/force-push. Zero migrations/importações/fixtures; nenhuma nova regra fiscal publicada/activada. Revisão/configuração/rotas conferidas; provas funcionais QA reutilizadas.","QA aceite reutilizada; execução ativa com backup/restauro, scan real, publicação expressa e HTTP anónimo200. Sem repetir percurso. outputs/investmoz-legado-ativacao-20261015/RESULTADO-FINAL.json; FINAL-READONLY.json; ANONYMOUS-HTTP.json; RECIBO-INTEGRIDADE-FINAL.json; outputs/investmoz-legado-restantes-setores-preparacao-20261015/INVENTARIO-E-RECORTE.json | 22/10/2026: primeiro incremento QA na branch codex/project-context-continuity-QA; contexto único por dossier/conta, herança com edições preservadas, moeda/IVA mensal e análise territorial explícita. Ver traceability-and-manual.md, secção Continuidade e adaptação contextual. 4 HTTP/74 asserções; 8 frontend; percurso visual A/B e nova sessão. Não encerra adaptação jurídica integral. | 22/10/2026 — percurso privado executável em QA (base52fbb146): condições oficiais seleccionam mero registo/autorização, alternativas documentais e próximos passos; contexto C v4 mero registo após distinção directo/indirecto (Lei14/R13); prévia visual, vínculo inactivo preservado e relatório v3 por autorização conservado como histórico. 3 testes/96 asserções e um teste do novo relatório, tipos/build aprovados. Sem validação jurídica genérica adicional; orientação permanente Tempo em AGENTS. Branch codex/private-investment-path-executable-QA; sem integração main/alteração da homologação/activação fiscal.",Implementado parcialmente — entradas setoriais e três artigos ativos,"Inventário reconciliado: 17 artigos e cinco imagens publicados; 31 artigos com corpo por integrar (5 setoriais, 8 trabalho doméstico, 18 históricos/noticiosos); Mercado Financeiro vazio e post 74364 sem título separados. Onze variantes de URL e 43 capturas adicionais de artigos já cobertas, sem novas identidades. Demais referências, anexos técnicos e sitemap misto conservam recorte próprio.",Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,URL antigo recupera a mesma fonte; login/retorno preservam a escolha; nova sessão recupera; nenhuma mistura entre projetos nem conversão de roteiro legado.,P1,"Legado post171985 modificado2026-04-20; categoria Oportunidades preservada como metadado, entidade guia. Metadados/sitemapInfopublica e área de investimento distintos; não remapear por nome.",USR-LEG-20261010-06,1,"[{""id"":""USR-LEG-20261010-06"",""pedido"":""Preservar contexto ao entrar/regressar ao percurso, URLs existentes e correspondências de migração"",""fontes"":[""Pedido direto10/10/2026 §6""],""aceitacao"":""URL antigo recupera a mesma fonte; login/retorno preservam a escolha; nova sessão recupera; nenhuma mistura entre projetos nem conversão de roteiro legado."",""estado"":""parcial"",""variantes"":""IntegraçãoprogressivaQA, sem substituição de pendências anteriores"",""modulo"":""legado/biblioteca/percurso"",""confirmacao_manual"":{""recebida_em"":""2026-10-10"",""fonte"":""Mensagem do responsável nesta conversa"",""conta"":""não indicada"",""perfil"":""não indicado"",""dispositivo"":""não indicado"",""criterios"":[{""criterio"":""criar_ou_escolher_dossier"",""estado"":""confirmado manualmente"",""ambito"":""piloto agronegócio QA""},{""criterio"":""guardar_referencia"",""estado"":""confirmado manualmente"",""ambito"":""piloto agronegócio QA""},{""criterio"":""nova_sessao"",""estado"":""confirmado manualmente"",""ambito"":""piloto agronegócio QA""},{""criterio"":""recuperar_dossier"",""estado"":""confirmado manualmente"",""ambito"":""piloto agronegócio QA""},{""criterio"":""abrir_artigo"",""estado"":""confirmado manualmente"",""ambito"":""piloto agronegócio QA""}],""exclusoes"":[""móvel"",""acessibilidade"",""outros perfis"",""C37 conta18"",""cenários A/B"",""cobertura integral""]},""incremento_setores_qa_20261010"":{""atualizado_em"":""2026-10-10T16:23:25.695297+00:00"",""ambito"":""QA18097;base55441isolada"",""evidencia"":""22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos/recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia200. Chromium desktop:16 artigos, pesquisa/imagens, Energia e Mineração distintas, C72 título preservado; QA21 criou4 dossiers, retorno, logout/novaMFA/F5/replay; QA23 negado403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP/Chromium, uma referência/evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence}-qa.json; legacy-financial-origin-20261010/proof.json. C37/QA18,A/B,móvel/acessibilidade/cobertura integral não encerrados."",""estado_requisito_atual"":""parcial"",""exclusoes"":[""ativação"",""C37/QA18"",""A/B"",""móvel"",""acessibilidade"",""cobertura integral""]},""incremento_visual_qa_20261010"":{""atualizado_em"":""2026-10-10T17:57:54.604301+00:00"",""ambito"":""QA18097/55441 exclusivamente"",""evidencia"":""FalhasC77–C83 corrigidas emQA: landmarks, nomeARIA do mapa, hierarquia de títulos do texto legado sem alteraroriginal/hash, tabelas financeiras focáveis por teclado, reflow de tarefas/select/data no dossier, langpt-MZ apenas no routerQA e proteção da recuperação assíncrona do simulador. Após correções15execuções axe/390–320–1440px,0violações automáticas/0overflow e idiomaPT; skiplink primeiroTab→conteúdo em3páginas; tabelas financeiras focadas/teclas no Chromium. Não equivale a leitor de ecrã, zoom/dispositivo real ou cobertura de todo oportal. LegacyContentTest5/84 e rastreioMFA1/14 são provas específicas, não contagem substituta de percursos. visual-followup-chromium-20261010.json e screenshots; históricos de falhas mantidos."",""lacuna_atual"":""Cobertura integral, mais perfis/dispositivos, leitor de ecrã e editor administrativoC74 não demonstrados. Mercado Financeiro permanece privado/corpo vazio confirmado na origem; rotas404. Sem associação automática Turismo→cadastro territorial, sem fundir Energia/Mineração."",""estado_global_preservado"":""parcial"",""ativacao"":false}}]","[Interface legado QA 10 /10/2026 ] Render /cliques observados no Chromium QA, com recuperação noutra sessão /F5 e negação à conta 23. Não é o navegador pessoal do utilizador nem o ensaio C37 /QA18. | Evidência anterior preservada: React preparado e build QA; dados Inertia recuperados. Navegador indisponível; roteiro manual em legado-piloto-qa.md . Aceitação visual pendente. | [Confirmação manual recebida 10 /10/2026 ] Responsável confirmou leitura pública → autenticação → criar /escolher dossier → guardar referência → nova sessão → recuperar dossier e abrir artigo. Confirmação declarada, sem conta /perfil/dispositivo/data de execução identificados. Não comprova MFA específico, ensaios móveis, acessibilidade, outros perfis, deduplicação, C37 /QA18 ou A /B. Ver legado-piloto-qa.md , confirmação manual. | [Setores QA após C71 10 /10/2026 ] 22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos /recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia 200. Chromium desktop:16 artigos, pesquisa /imagens , Energia e Mineração distintas, C72 título preservado; QA21 criou 4 dossiers, retorno, logout /novaMFA/F5/replay ; QA23 negado 403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP /Chromium , uma referência /evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence} -qa.json ; legacy-financial-origin-20261010 /proof.json. C37 /QA18 ,A /B ,móvel /acessibilidade/cobertura integral não encerrados. | [Visual QA 10 /10/2026 ] Leitura pública /móvel dirigida, teclado e 4 consumidores do mapa demonstrados;15 execuções de acessibilidade sem violação automática. | [Visual QA 10/10/2026] Leitura pública/móvel dirigida, teclado e4consumidores do mapa demonstrados;15execuções de acessibilidade semviolação automática.","GET públicos e escritas autenticadas no servidor18097, alvo real55441 confirmado; publicação separada do importador. | [Setores QA após C71 10/10/2026] 22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos/recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia200. Chromium desktop:16 artigos, pesquisa/imagens, Energia e Mineração distintas, C72 título preservado; QA21 criou4 dossiers, retorno, logout/novaMFA/F5/replay; QA23 negado403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP/Chromium, uma referência/evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence}-qa.json; legacy-financial-origin-20261010/proof.json. C37/QA18,A/B,móvel/acessibilidade/cobertura integral não encerrados.","Dois recursos na biblioteca existente e referências no payload cifrado do dossier; sem nova tabela/cadastro paralelo. | [Confirmação manual recebida 10/10/2026] Responsável confirmou leitura pública → autenticação → criar/escolher dossier → guardar referência → nova sessão → recuperar dossier e abrir artigo. Confirmação declarada, sem conta/perfil/dispositivo/data de execução identificados. Não comprova MFA específico, ensaios móveis, acessibilidade, outros perfis, deduplicação, C37/QA18 ou A/B. Ver legado-piloto-qa.md, confirmação manual. | [Setores QA após C71 10/10/2026] 22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos/recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia200. Chromium desktop:16 artigos, pesquisa/imagens, Energia e Mineração distintas, C72 título preservado; QA21 criou4 dossiers, retorno, logout/novaMFA/F5/replay; QA23 negado403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP/Chromium, uma referência/evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence}-qa.json; legacy-financial-origin-20261010/proof.json. C37/QA18,A/B,móvel/acessibilidade/cobertura integral não encerrados.","[Interface legado QA 10/10/2026] Render/cliques observados no Chromium QA, com recuperação noutra sessão/F5 e negação à conta23. Não é o navegador pessoal do utilizador nem o ensaio C37/QA18. | Evidência anterior preservada: Logout/nova sessão FortifyMFA21: fonte/versão/hashes recuperados; outra conta negada e projeto independente sem referência. | [Confirmação manual recebida 10/10/2026] Responsável confirmou leitura pública → autenticação → criar/escolher dossier → guardar referência → nova sessão → recuperar dossier e abrir artigo. Confirmação declarada, sem conta/perfil/dispositivo/data de execução identificados. Não comprova MFA específico, ensaios móveis, acessibilidade, outros perfis, deduplicação, C37/QA18 ou A/B. Ver legado-piloto-qa.md, confirmação manual. | [Setores QA após C71 10/10/2026] 22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos/recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia200. Chromium desktop:16 artigos, pesquisa/imagens, Energia e Mineração distintas, C72 título preservado; QA21 criou4 dossiers, retorno, logout/novaMFA/F5/replay; QA23 negado403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP/Chromium, uma referência/evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence}-qa.json; legacy-financial-origin-20261010/proof.json. C37/QA18,A/B,móvel/acessibilidade/cobertura integral não encerrados.",Piloto ativo encerrado; restante legado pendente.,Piloto agronegócio: ativo e entrega encerrada. Integração integral do legado: pendente nos mesmos IDs.,parcial,Não disponibilizado; guarda QA/flagfalse. Nenhuma escrita ou divulgação ativa autorizada.,"15/10/2026: entrega do piloto encerrada; dados/B/COUNTRY02/build preservados. Não equivale a integração integral do legado. | Lote setorial disponibilizado por autorização expressa da Tempo; integração integral continua pendente. | QA 15/10/2026: setores-fintech-QA-d5b4dc354265; sete entradas comerciais/contexto no dossier e três artigos preparados. B/COUNTRY02/aceitações preservados; sem disponibilização ativa. | Disponibilização expressamente autorizada pela Tempo: «Autorizo a disponibilizar». Executada com backup/restauro fresco verificado; apenas conferência operacional, sem repetir aceitação QA.
+AUD-LEG-06,"Preservar contexto ao entrar/regressar ao percurso, URLs existentes e correspondências de migração","Pedido direto do responsável,10/10/2026, integração do legado emQA §6; https://investemoz.tempo.co.mz/; legado-piloto-qa.md Pedido expresso da Tempo, 23/10/2026, nesta retoma: corrigir integração de complementos no percurso actual, com identidade, cadeia de valor, localização e relações documentadas.",biblioteca / conteúdo público / percurso do investidor,/explorar/agronegocio; /agronegocio; /documentos/6; /investimentos/a-partir-de/agronegocio; /investimentos/{id}/conteudos,"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas. Capacidade existente associada ao domínio; correspondência integral desta cláusula só quando demonstrada na prova individual.","Disponibilizado em 15/10/2026, setores-fintech-QA-d5b4dc354265 DOC01: 16 fontes e compilação; sete entradas setoriais e especialização Fintech no dossier; três artigos publicados (recursos reais 27/28/29), imagem 24 reutilizada por identidade/hash. Flags existentes preservadas; sem migrations/categorias novas. B e COUNTRY02 preservados. | 22/10/2026 — disponibilizado por autorização Tempo: revisão servida042ffbde (inclui a76369eb/a1fbda06/064296e1 e correcção dirigida da recuperação legada). Percurso habilitado na homologação, versão private-investment-preparation-2026-v1; main ancestral preservado, sem conflitos/force-push. Zero migrations/importações/fixtures; nenhuma nova regra fiscal publicada/activada. Revisão/configuração/rotas conferidas; provas funcionais QA reutilizadas.","QA aceite reutilizada; execução ativa com backup/restauro, scan real, publicação expressa e HTTP anónimo200. Sem repetir percurso. outputs/investmoz-legado-ativacao-20261015/RESULTADO-FINAL.json; FINAL-READONLY.json; ANONYMOUS-HTTP.json; RECIBO-INTEGRIDADE-FINAL.json; outputs/investmoz-legado-restantes-setores-preparacao-20261015/INVENTARIO-E-RECORTE.json | 22/10/2026: primeiro incremento QA na branch codex/project-context-continuity-QA; contexto único por dossier/conta, herança com edições preservadas, moeda/IVA mensal e análise territorial explícita. Ver traceability-and-manual.md, secção Continuidade e adaptação contextual. 4 HTTP/74 asserções; 8 frontend; percurso visual A/B e nova sessão. Não encerra adaptação jurídica integral. | 22/10/2026 — percurso privado executável em QA (base52fbb146): condições oficiais seleccionam mero registo/autorização, alternativas documentais e próximos passos; contexto C v4 mero registo após distinção directo/indirecto (Lei14/R13); prévia visual, vínculo inactivo preservado e relatório v3 por autorização conservado como histórico. 3 testes/96 asserções e um teste do novo relatório, tipos/build aprovados. Sem validação jurídica genérica adicional; orientação permanente Tempo em AGENTS. Branch codex/private-investment-path-executable-QA; sem integração main/alteração da homologação/activação fiscal.",Implementado parcialmente — entradas setoriais e três artigos ativos,"Inventário reconciliado: 17 artigos e cinco imagens publicados; 31 artigos com corpo por integrar (5 setoriais, 8 trabalho doméstico, 18 históricos/noticiosos); Mercado Financeiro vazio e post 74364 sem título separados. Onze variantes de URL e 43 capturas adicionais de artigos já cobertas, sem novas identidades. Demais referências, anexos técnicos e sitemap misto conservam recorte próprio.",Scanner/worker/GD/WebP e originais privados; ACL por oportunidade/sala diferente de partilha individual não implementada. LegadoOFF. Nenhuma nova decisão identificada para reconciliar/demonstrar esta cláusula. Decisões específicas só após localizar a regra correspondente.,URL antigo recupera a mesma fonte; login/retorno preservam a escolha; nova sessão recupera; nenhuma mistura entre projetos nem conversão de roteiro legado.,P1,"Legado post171985 modificado2026-04-20; categoria Oportunidades preservada como metadado, entidade guia. Metadados/sitemapInfopublica e área de investimento distintos; não remapear por nome.",USR-LEG-20261010-06,1,"[{""id"":""USR-LEG-20261010-06"",""pedido"":""Preservar contexto ao entrar/regressar ao percurso, URLs existentes e correspondências de migração"",""fontes"":[""Pedido direto10/10/2026 §6""],""aceitacao"":""URL antigo recupera a mesma fonte; login/retorno preservam a escolha; nova sessão recupera; nenhuma mistura entre projetos nem conversão de roteiro legado."",""estado"":""parcial"",""variantes"":""IntegraçãoprogressivaQA, sem substituição de pendências anteriores"",""modulo"":""legado/biblioteca/percurso"",""confirmacao_manual"":{""recebida_em"":""2026-10-10"",""fonte"":""Mensagem do responsável nesta conversa"",""conta"":""não indicada"",""perfil"":""não indicado"",""dispositivo"":""não indicado"",""criterios"":[{""criterio"":""criar_ou_escolher_dossier"",""estado"":""confirmado manualmente"",""ambito"":""piloto agronegócio QA""},{""criterio"":""guardar_referencia"",""estado"":""confirmado manualmente"",""ambito"":""piloto agronegócio QA""},{""criterio"":""nova_sessao"",""estado"":""confirmado manualmente"",""ambito"":""piloto agronegócio QA""},{""criterio"":""recuperar_dossier"",""estado"":""confirmado manualmente"",""ambito"":""piloto agronegócio QA""},{""criterio"":""abrir_artigo"",""estado"":""confirmado manualmente"",""ambito"":""piloto agronegócio QA""}],""exclusoes"":[""móvel"",""acessibilidade"",""outros perfis"",""C37 conta18"",""cenários A/B"",""cobertura integral""]},""incremento_setores_qa_20261010"":{""atualizado_em"":""2026-10-10T16:23:25.695297+00:00"",""ambito"":""QA18097;base55441isolada"",""evidencia"":""22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos/recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia200. Chromium desktop:16 artigos, pesquisa/imagens, Energia e Mineração distintas, C72 título preservado; QA21 criou4 dossiers, retorno, logout/novaMFA/F5/replay; QA23 negado403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP/Chromium, uma referência/evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence}-qa.json; legacy-financial-origin-20261010/proof.json. C37/QA18,A/B,móvel/acessibilidade/cobertura integral não encerrados."",""estado_requisito_atual"":""parcial"",""exclusoes"":[""ativação"",""C37/QA18"",""A/B"",""móvel"",""acessibilidade"",""cobertura integral""]},""incremento_visual_qa_20261010"":{""atualizado_em"":""2026-10-10T17:57:54.604301+00:00"",""ambito"":""QA18097/55441 exclusivamente"",""evidencia"":""FalhasC77–C83 corrigidas emQA: landmarks, nomeARIA do mapa, hierarquia de títulos do texto legado sem alteraroriginal/hash, tabelas financeiras focáveis por teclado, reflow de tarefas/select/data no dossier, langpt-MZ apenas no routerQA e proteção da recuperação assíncrona do simulador. Após correções15execuções axe/390–320–1440px,0violações automáticas/0overflow e idiomaPT; skiplink primeiroTab→conteúdo em3páginas; tabelas financeiras focadas/teclas no Chromium. Não equivale a leitor de ecrã, zoom/dispositivo real ou cobertura de todo oportal. LegacyContentTest5/84 e rastreioMFA1/14 são provas específicas, não contagem substituta de percursos. visual-followup-chromium-20261010.json e screenshots; históricos de falhas mantidos."",""lacuna_atual"":""Cobertura integral, mais perfis/dispositivos, leitor de ecrã e editor administrativoC74 não demonstrados. Mercado Financeiro permanece privado/corpo vazio confirmado na origem; rotas404. Sem associação automática Turismo→cadastro territorial, sem fundir Energia/Mineração."",""estado_global_preservado"":""parcial"",""ativacao"":false}}]","[Interface legado QA 10 /10/2026 ] Render /cliques observados no Chromium QA, com recuperação noutra sessão /F5 e negação à conta 23. Não é o navegador pessoal do utilizador nem o ensaio C37 /QA18. | Evidência anterior preservada: React preparado e build QA; dados Inertia recuperados. Navegador indisponível; roteiro manual em legado-piloto-qa.md . Aceitação visual pendente. | [Confirmação manual recebida 10 /10/2026 ] Responsável confirmou leitura pública → autenticação → criar /escolher dossier → guardar referência → nova sessão → recuperar dossier e abrir artigo. Confirmação declarada, sem conta /perfil/dispositivo/data de execução identificados. Não comprova MFA específico, ensaios móveis, acessibilidade, outros perfis, deduplicação, C37 /QA18 ou A /B. Ver legado-piloto-qa.md , confirmação manual. | [Setores QA após C71 10 /10/2026 ] 22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos /recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia 200. Chromium desktop:16 artigos, pesquisa /imagens , Energia e Mineração distintas, C72 título preservado; QA21 criou 4 dossiers, retorno, logout /novaMFA/F5/replay ; QA23 negado 403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP /Chromium , uma referência /evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence} -qa.json ; legacy-financial-origin-20261010 /proof.json. C37 /QA18 ,A /B ,móvel /acessibilidade/cobertura integral não encerrados. | [Visual QA 10 /10/2026 ] Leitura pública /móvel dirigida, teclado e 4 consumidores do mapa demonstrados;15 execuções de acessibilidade sem violação automática. | [Visual QA 10/10/2026] Leitura pública/móvel dirigida, teclado e4consumidores do mapa demonstrados;15execuções de acessibilidade semviolação automática.","GET públicos e escritas autenticadas no servidor18097, alvo real55441 confirmado; publicação separada do importador. | [Setores QA após C71 10/10/2026] 22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos/recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia200. Chromium desktop:16 artigos, pesquisa/imagens, Energia e Mineração distintas, C72 título preservado; QA21 criou4 dossiers, retorno, logout/novaMFA/F5/replay; QA23 negado403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP/Chromium, uma referência/evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence}-qa.json; legacy-financial-origin-20261010/proof.json. C37/QA18,A/B,móvel/acessibilidade/cobertura integral não encerrados.","Dois recursos na biblioteca existente e referências no payload cifrado do dossier; sem nova tabela/cadastro paralelo. | [Confirmação manual recebida 10/10/2026] Responsável confirmou leitura pública → autenticação → criar/escolher dossier → guardar referência → nova sessão → recuperar dossier e abrir artigo. Confirmação declarada, sem conta/perfil/dispositivo/data de execução identificados. Não comprova MFA específico, ensaios móveis, acessibilidade, outros perfis, deduplicação, C37/QA18 ou A/B. Ver legado-piloto-qa.md, confirmação manual. | [Setores QA após C71 10/10/2026] 22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos/recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia200. Chromium desktop:16 artigos, pesquisa/imagens, Energia e Mineração distintas, C72 título preservado; QA21 criou4 dossiers, retorno, logout/novaMFA/F5/replay; QA23 negado403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP/Chromium, uma referência/evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence}-qa.json; legacy-financial-origin-20261010/proof.json. C37/QA18,A/B,móvel/acessibilidade/cobertura integral não encerrados.","[Interface legado QA 10/10/2026] Render/cliques observados no Chromium QA, com recuperação noutra sessão/F5 e negação à conta23. Não é o navegador pessoal do utilizador nem o ensaio C37/QA18. | Evidência anterior preservada: Logout/nova sessão FortifyMFA21: fonte/versão/hashes recuperados; outra conta negada e projeto independente sem referência. | [Confirmação manual recebida 10/10/2026] Responsável confirmou leitura pública → autenticação → criar/escolher dossier → guardar referência → nova sessão → recuperar dossier e abrir artigo. Confirmação declarada, sem conta/perfil/dispositivo/data de execução identificados. Não comprova MFA específico, ensaios móveis, acessibilidade, outros perfis, deduplicação, C37/QA18 ou A/B. Ver legado-piloto-qa.md, confirmação manual. | [Setores QA após C71 10/10/2026] 22 originais importados privadamente após prévia renovada, hashes recuperados,22 scans ClamD reais e replay sem novos documentos/recursos/auditoria/scans. Divulgação autenticada separada:16 artigos com texto+5 imagens públicos; Mercado Financeiro privado, vazio confirmado na origem HTML e Inertia200. Chromium desktop:16 artigos, pesquisa/imagens, Energia e Mineração distintas, C72 título preservado; QA21 criou4 dossiers, retorno, logout/novaMFA/F5/replay; QA23 negado403 e anónimo sem contexto. Persistência READ ONLY:8 dossiers HTTP/Chromium, uma referência/evento cada,22 hashes únicos,0 relações geográficas automáticas. legacy-sectors-{apply,replay,http,browser,persistence}-qa.json; legacy-financial-origin-20261010/proof.json. C37/QA18,A/B,móvel/acessibilidade/cobertura integral não encerrados.",Piloto ativo encerrado; restante legado pendente.,Piloto agronegócio: ativo e entrega encerrada. Integração integral do legado: pendente nos mesmos IDs.,parcial,Não disponibilizado; guarda QA/flagfalse. Nenhuma escrita ou divulgação ativa autorizada.,"23/10/2026: anchor integration executable in isolated QA; 4 tests/116 assertions + 2 frontend tests; 28 accepted territorial links recovered in QA, 29 real published fiches preserved. Receipt docs/investmoz/unification/anchor-integration-receipt-20261023.json. Homologation still 8036b9b0 until Git installation and exact 28-link recovery; no accepted proofs repeated; statistics/AI deferred. | 15/10/2026: entrega do piloto encerrada; dados/B/COUNTRY02/build preservados. Não equivale a integração integral do legado. | Lote setorial disponibilizado por autorização expressa da Tempo; integração integral continua pendente. | QA 15/10/2026: setores-fintech-QA-d5b4dc354265; sete entradas comerciais/contexto no dossier e três artigos preparados. B/COUNTRY02/aceitações preservados; sem disponibilização ativa. | Disponibilização expressamente autorizada pela Tempo: «Autorizo a disponibilizar». Executada com backup/restauro fresco verificado; apenas conferência operacional, sem repetir aceitação QA.
-[RECONCILIACAO-43-20261019] 5: Sem saldo de código no recorte visual aceite. | 8: Outras identidades do legado exigem lotes e eventual adaptação por tipo. Não há autorização genérica para publicar todo o acervo. | 22/10/2026: primeiro incremento QA na branch codex/project-context-continuity-QA; contexto único por dossier/conta, herança com edições preservadas, moeda/IVA mensal e análise territorial explícita. Ver traceability-and-manual.md, secção Continuidade e adaptação contextual. 4 HTTP/74 asserções; 8 frontend; percurso visual A/B e nova sessão. Não encerra adaptação jurídica integral. | 22/10/2026 — percurso privado executável em QA (base52fbb146): condições oficiais seleccionam mero registo/autorização, alternativas documentais e próximos passos; contexto C v4 mero registo após distinção directo/indirecto (Lei14/R13); prévia visual, vínculo inactivo preservado e relatório v3 por autorização conservado como histórico. 3 testes/96 asserções e um teste do novo relatório, tipos/build aprovados. Sem validação jurídica genérica adicional; orientação permanente Tempo em AGENTS. Branch codex/private-investment-path-executable-QA; sem integração main/alteração da homologação/activação fiscal.","Inventário reconciliado: 20 artigos e cinco imagens publicados; 28 artigos com corpo por integrar (2 setoriais, 8 trabalho doméstico, 18 históricos/noticiosos); Mercado Financeiro vazio e post 74364 sem título separados. Onze variantes de URL e 43 capturas adicionais de artigos já cobertas, sem novas identidades. Demais referências, anexos técnicos e sitemap misto conservam recorte próprio. | Entrega operacional deste delta concluída. Mercado Financeiro geral vazio e restante acervo mantêm os seus estados. Licenças, requisitos e documentos específicos Fintech por atividade permanecem por determinar; não bloqueiam a preparação independente nem se consideram concluídos. | Recorte QA demonstrado, sem encerrar critérios globais. Histórico económico combinado conservado, fora de novas escolhas; oportunidade6 não inferida como Fintech. Sem fusões por nome. Recuperação existente conferida por leitura e hashes; outra sessão/dispositivo e percursos aceites não reensaiados. Conferência dos anexos pelo utilizador pendente. | Recorte aprovado disponibilizado; requisitos globais permanecem abertos. Atividade historica combinada e oportunidade6 sem reclassificacao. Conferencia dos anexos finais pelo utilizador pendente. Sem repetir testes aceites, formularios ou L1.
-
-[UTILIZACAO-HOMOLOGACAO-20261019] 5: Disponibilidade condicionada conforme limite registado — Ecrã aberto: dez sectores principais, especialização Fintech sem cartão principal duplicado; 12 registos conservados. | 8: Disponibilidade condicionada conforme limite registado — Adaptador habilitado; artigos/imagens transportados privadamente, sem os publicar. | Recorte executável C concluído em QA. Restantes coberturas sectoriais/benefícios e encaminhamento visual de zona real têm limites concretos no manual; não bloqueiam os ramos já documentados. Integração/habilitação no destino não executadas. | Integração/habilitação deste recorte executadas em22/10/2026; referências anteriores a operação pendente são históricas. Não reabrir as provas aceites. Delta de complementos preparado/verificado em QA; conferência visual e instalação no destino ainda não realizadas. Relações sem oferta identificada permanecem necessidades, sem presumir inexistência no acervo. Cobertura transversal e restantes pendências desta linha mantêm-se. Actualização visual 23/10/2026: supera apenas a pendência visual dos complementos no recorte documentado. Não demonstra contextos específicos de várias oportunidades em zonas/parques, Terra/DUAT, Balcão ou manifestação. Sem disponibilização no destino nem fecho global. | [Saldo corrente 23/10/2026] São três lacunas de integração constatadas por leitura e quatro verificações delimitadas, não sete falhas de execução. Os itens 1–3 determinam a correcção executável seguinte; 4–6 podem ser conferidos independentemente em QA isolado; 7 depende apenas do âmbito corrigido. A contagem refere-se a estes sete recortes, não a cada formato ou campo. Uma verificação que passe encerra o item; uma que falhe regista o defeito concreto na mesma linha da matriz. Não criar outra matriz/backlog nem converter ausência de prova em regressão. Fechos preservados: 6b544548/4098192a; d8224ba8/af926180; 55136b44/b6a626c9. Notas historicas de falta de entrega destes recortes estao superadas. Ver sete recortes no inicio do manual existente. | [QA conjunta 23/10/2026] Itens 1-3 corrigidos: escolha de oportunidade no simulador, aplicabilidade/estados por oportunidade, atalho Terra pelo pedido associado. Provas dirigidas novas nos itens 4-6: retirada da primeira, contactos autorizados, entradas ideia/sector/territorio e login. Word/ZIP gerados; composicao de impressao conferida. Resta PDF nativo efectivamente guardado/paginacao e recorte ancora por analisar. Sem entrega na homologacao desta candidata. Ver estado corrente no inicio do manual; sete itens historicos abaixo nao sao o saldo corrente. Fechos 6b544548, d8224ba8, 55136b44 preservados. Estatisticas e IA adiadas. | [PDF nativo 23/10/2026] Falhas observadas na saida real: not_started e detalhe dos requisitos ausente. Correcao 2856240c sobre candidata 1afdfee8: estados humanos e requisitos apenas da oportunidade aplicavel. Teste novo native-pdf-scope passou; tipos/build passaram; sem repetir Word/ZIP. Saida real revista13, oportunidade309/Manica, valores QA123456/45678/diferenca77778MZN, pronta para gravacao manual. PDF guardado/paginacao pendentes por falta de controlo do dialogo nativo. Integracao/disponibilizacao ja autorizada pela Tempo apos conferencia, ainda nao executada; origin/main55136b44. Estatisticas e IA adiadas. [Analise corrente 23/10/2026] Recorte ancora analisado: duas lacunas de implementacao (filtro sectorial combinado com localizacao e ideia directa a partir de ancora sem oferta); uma reconciliacao de dados/ambiente e uma prova dirigida de interesse/login. Quinze fichas documentais QA mantem texto de sector/localizacao/regiao, sem correspondencias territoriais canonicas nem oferta publica directa nesse clone; ficha SYNTHETIC QA separada. Nao inferir perda na homologacao. Preservar recibo de 29 fichas e continuidade via oportunidade ja aceite. Ver inicio do manual para escopo, fontes e criterios; nenhuma implementacao de ancoras nesta passagem. | [PDF nativo guardado conferido 23/10/2026] Original encontrado na pasta indicada com titulo automatico Relatorio SYNTHETIC QA, extensao .pdf, maquina ONALA/macbook/Console. SHA256010eb4ea12015563c1b2f8bc255b1078c276f824c50690732541d5bffe34b8a6. Dez paginas renderizadas e conferidas: oportunidade309/Manica, cinco requisitos especificos, valores123456/45678/diferenca77778MZN; paginacao e legibilidade aprovadas. Sem regenerar PDF ou repetir Word/ZIP/provas aceites. Condicao satisfeita para1afdfee8+2856240c; disponibilizacao Git autorizada em execucao, ainda a confirmar instalada. Ver inicio do manual e native-pdf-and-anchor-review-20261023.json. Pendencias historicas de ficheiro em falta superadas; saldo de ancoras6985f82e preservado; Estatisticas/IA adiadas. | [Entrega confirmada 23/10/2026] 1afdfee8+2856240c entregues na homologacao8036b9b0. PDF original encontrado pelo titulo automatico na mesma pasta/maquina/sessao: dez paginas e ambito/requisitos/valores/paginacao conferidos, SHA256010eb4ea12015563c1b2f8bc255b1078c276f824c50690732541d5bffe34b8a6, sem regeneracao. Fast-forward55136b44->8036b9b0, instalador installed16:46:13UTC, zero migrations/importacoes. Revisao publica e15hashes funcionais coincidem; delta autenticado na ficha53/dossier958df138 verificado, versao5 preservada, zero novos pedidos/gravacoes/submissoes. Sem repetir provas aceites. Ver treatment-scope-installation-receipt-20261023.json e inicio do manual. Pendencias historicas de PDF/instalacao superadas neste recorte. Complementos e fechos anteriores preservados. Saldo ancora6985f82e mantido; Estatisticas/IA adiadas; sem fecho global.","documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas","Dependências operacionais desta entrega resolvidas: hashes, backup/restauro fresco, conta autenticada, scans e publicações. Dependências regulatórias específicas e editoriais restantes preservadas no critério atual. | Origem: pedido expresso da Tempo de18/10. IDs, especialização por leitura e ponte histórica são escolhas técnicas; sem nova regra organizacional. Ativo inalterado; disponibilização separada. Sem migration/instalação140000/150000; reversão retém somente a rota nova Fintech além dos dados/histórico e associação2→8. Estados e critérios anteriores preservados. | Origem: autorizacao expressa Tempo18/10/2026. Backup/restauro e execucao autenticada concluidos; 140000/150000 presentes uma vez, sem migrations. Reversao parcial preserva dados/auditoria/esquemas e rota compativel Fintech. Matriz/manual/backlog atuais preservados. Ficha integral dos parques separada.","Autorização Tempo para setores-fintech-QA-d5b4dc354265 DOC01 executada, limitada a 16 fontes/compilação e três artigos. Decisões fora deste recorte mantêm-se; nenhuma publicação do restante acervo.",Delta disponibilizado; pendências fora do recorte continuam na mesma matriz.,"Saldo operacional desta entrega: zero. A faixa 1h30–3h era estimativa, não saldo atual. Esforço das lacunas remanescentes depende de delimitação concreta; não repetir aceitações.","outputs/investmoz-legado-ativacao-20261015/RESULTADO-FINAL.json; FINAL-READONLY.json; ANONYMOUS-HTTP.json; RECIBO-INTEGRIDADE-FINAL.json; outputs/investmoz-legado-restantes-setores-preparacao-20261015/INVENTARIO-E-RECORTE.json | 15/10/2026: outputs/investmoz-legado-setores-ativacao-20261015/FINAL-READONLY.json; ANONYMOUS-HTTP.json; SOURCE-DELIVERY.json; FRESH-BACKUP.json. 20 importados privados, scan clean e publicados pela sessão Osmane Nala (2); registos de negócio anteriores preservados. | 15/10/2026: outputs/investmoz-legado-inventario-reconciliado-20261015/SALDO-LEGADO.md; RECONCILIACAO-LEGADO.json; LEITURA-ESTADO.json; inventários existentes atualizados por identidade/versão/hash. | outputs/investmoz-fintech-investimento-QA-20261015/RESULTADO-QA.md; PROVA-DELTA-QA.json; HTTP-DELTA-QA.json; PROVA-FINAL-DELTA-QA.json; HTTP-RECUPERACAO-FINAL-QA.json; MANIFESTO-ENTREGA.json | outputs/investmoz-setores-fintech-ativacao-20261015/RELATORIO-ENTREGA.md; PUBLISHED.json; PRESERVACAO-FINAL.json; HTTP-OPERACIONAL.json; FRESH-BACKUP.json; RECIBO-FINAL.json | 18/10: sectores-duplicacoes-QA-9b6097f97121, organização sectorial/duplicações apenas QA. Energia8/Mineração7; Fintech9 especialização de Mercado6; oportunidade2 reclassificada2→8 sem duplicação; 56HTTP,30serviço,3SQL e5reversão observados. Relatório e manifesto exatos em outputs/investmoz-sectores-duplicacoes-QA-20261018/para-revisao/. | 18/10/2026: disponibilizada sectores-duplicacoes-QA-e9f7d821b6f7 em investemoz:5432, procedimento DOC02. Backup/restauro fresco validado. 34 fontes/167 build. Conta2 com permissao/MFA; oportunidade2 sector2 para8; evento/recibo unicos, operacao27e6a658-d8bc-4d94-ab7b-b977ba56d141. Mesma transacao/ligacao e limpeza SET LOCAL observadas. Provas em outputs/investmoz-sectores-duplicacoes-ativacao-20261018/CONFERENCIA-FINAL.json e para-revisao/RECIBO-EXECUCAO.json. | Homologação teste-investidor 19/10/2026: Sectores e duplicação visual=Instalado mas desabilitado; Legado — conteúdo restante=Instalado mas desabilitado. Saldo derivado e limites em outputs/investmoz-disponibilizacao-integral-20261019/SALDO-E-ACTUALIZACAO-CONSOLIDADA.md. Não substitui estado/provas do activo; trecho documental encerrado, vínculo dossier aberto. | Proposta integral fdcb31f1b5b9: aplicação activa local completa + R2/DOC01/destino reconciliados; schema/build/recuperação de contexto e reversão de apresentação ensaiados no clone isolado. Não instalado remotamente. Inc. QA territoriais/Inhambane/programas separados. Limites e decisões em outputs/investmoz-disponibilizacao-integral-20261019/PROPOSTA-INTEGRAL-PARA-DECISAO.md. | Execução autorizada fdcb31f1b5b9 concluída em teste-investidor: Sectores e duplicação visual=Disponível; Legado — conteúdo restante=Instalado mas desabilitado. 1080 hashes iguais, schema171/88, custódia/scan/recuperação reais. Sem publicação ou papéis novos. Vínculo dossier legítimo pendente; incrementos QA separados. Limites em outputs/investmoz-disponibilizacao-integral-20261019/RESULTADO-DISPONIBILIZACAO-INTEGRAL.md; não encerra critérios globais não demonstrados.
+[RECONCILIACAO-43-20261019] 5: Sem saldo de código no recorte visual aceite. | 8: Outras identidades do legado exigem lotes e eventual adaptação por tipo. Não há autorização genérica para publicar todo o acervo. | 22/10/2026: primeiro incremento QA na branch codex/project-context-continuity-QA; contexto único por dossier/conta, herança com edições preservadas, moeda/IVA mensal e análise territorial explícita. Ver traceability-and-manual.md, secção Continuidade e adaptação contextual. 4 HTTP/74 asserções; 8 frontend; percurso visual A/B e nova sessão. Não encerra adaptação jurídica integral. | 22/10/2026 — percurso privado executável em QA (base52fbb146): condições oficiais seleccionam mero registo/autorização, alternativas documentais e próximos passos; contexto C v4 mero registo após distinção directo/indirecto (Lei14/R13); prévia visual, vínculo inactivo preservado e relatório v3 por autorização conservado como histórico. 3 testes/96 asserções e um teste do novo relatório, tipos/build aprovados. Sem validação jurídica genérica adicional; orientação permanente Tempo em AGENTS. Branch codex/private-investment-path-executable-QA; sem integração main/alteração da homologação/activação fiscal.",Anchor slice: Git installation; authenticated exact 28-link recovery after verified backup/restore; installed delta. Tempo final navigation/presentation review. Previous accepted closures preserved.,"documents, biblioteca, importação autenticada, VerifiedDocumentBinary, jobs/derivadas","Dependências operacionais desta entrega resolvidas: hashes, backup/restauro fresco, conta autenticada, scans e publicações. Dependências regulatórias específicas e editoriais restantes preservadas no critério atual. | Origem: pedido expresso da Tempo de18/10. IDs, especialização por leitura e ponte histórica são escolhas técnicas; sem nova regra organizacional. Ativo inalterado; disponibilização separada. Sem migration/instalação140000/150000; reversão retém somente a rota nova Fintech além dos dados/histórico e associação2→8. Estados e critérios anteriores preservados. | Origem: autorizacao expressa Tempo18/10/2026. Backup/restauro e execucao autenticada concluidos; 140000/150000 presentes uma vez, sem migrations. Reversao parcial preserva dados/auditoria/esquemas e rota compativel Fintech. Matriz/manual/backlog atuais preservados. Ficha integral dos parques separada.","Autorização Tempo para setores-fintech-QA-d5b4dc354265 DOC01 executada, limitada a 16 fontes/compilação e três artigos. Decisões fora deste recorte mantêm-se; nenhuma publicação do restante acervo.",Delta disponibilizado; pendências fora do recorte continuam na mesma matriz.,"Saldo operacional desta entrega: zero. A faixa 1h30–3h era estimativa, não saldo atual. Esforço das lacunas remanescentes depende de delimitação concreta; não repetir aceitações.","23/10/2026: anchor integration executable in isolated QA; 4 tests/116 assertions + 2 frontend tests; 28 accepted territorial links recovered in QA, 29 real published fiches preserved. Receipt docs/investmoz/unification/anchor-integration-receipt-20261023.json. Homologation still 8036b9b0 until Git installation and exact 28-link recovery; no accepted proofs repeated; statistics/AI deferred. | outputs/investmoz-legado-ativacao-20261015/RESULTADO-FINAL.json; FINAL-READONLY.json; ANONYMOUS-HTTP.json; RECIBO-INTEGRIDADE-FINAL.json; outputs/investmoz-legado-restantes-setores-preparacao-20261015/INVENTARIO-E-RECORTE.json | 15/10/2026: outputs/investmoz-legado-setores-ativacao-20261015/FINAL-READONLY.json; ANONYMOUS-HTTP.json; SOURCE-DELIVERY.json; FRESH-BACKUP.json. 20 importados privados, scan clean e publicados pela sessão Osmane Nala (2); registos de negócio anteriores preservados. | 15/10/2026: outputs/investmoz-legado-inventario-reconciliado-20261015/SALDO-LEGADO.md; RECONCILIACAO-LEGADO.json; LEITURA-ESTADO.json; inventários existentes atualizados por identidade/versão/hash. | outputs/investmoz-fintech-investimento-QA-20261015/RESULTADO-QA.md; PROVA-DELTA-QA.json; HTTP-DELTA-QA.json; PROVA-FINAL-DELTA-QA.json; HTTP-RECUPERACAO-FINAL-QA.json; MANIFESTO-ENTREGA.json | outputs/investmoz-setores-fintech-ativacao-20261015/RELATORIO-ENTREGA.md; PUBLISHED.json; PRESERVACAO-FINAL.json; HTTP-OPERACIONAL.json; FRESH-BACKUP.json; RECIBO-FINAL.json | 18/10: sectores-duplicacoes-QA-9b6097f97121, organização sectorial/duplicações apenas QA. Energia8/Mineração7; Fintech9 especialização de Mercado6; oportunidade2 reclassificada2→8 sem duplicação; 56HTTP,30serviço,3SQL e5reversão observados. Relatório e manifesto exatos em outputs/investmoz-sectores-duplicacoes-QA-20261018/para-revisao/. | 18/10/2026: disponibilizada sectores-duplicacoes-QA-e9f7d821b6f7 em investemoz:5432, procedimento DOC02. Backup/restauro fresco validado. 34 fontes/167 build. Conta2 com permissao/MFA; oportunidade2 sector2 para8; evento/recibo unicos, operacao27e6a658-d8bc-4d94-ab7b-b977ba56d141. Mesma transacao/ligacao e limpeza SET LOCAL observadas. Provas em outputs/investmoz-sectores-duplicacoes-ativacao-20261018/CONFERENCIA-FINAL.json e para-revisao/RECIBO-EXECUCAO.json. | Homologação teste-investidor 19/10/2026: Sectores e duplicação visual=Instalado mas desabilitado; Legado — conteúdo restante=Instalado mas desabilitado. Saldo derivado e limites em outputs/investmoz-disponibilizacao-integral-20261019/SALDO-E-ACTUALIZACAO-CONSOLIDADA.md. Não substitui estado/provas do activo; trecho documental encerrado, vínculo dossier aberto. | Proposta integral fdcb31f1b5b9: aplicação activa local completa + R2/DOC01/destino reconciliados; schema/build/recuperação de contexto e reversão de apresentação ensaiados no clone isolado. Não instalado remotamente. Inc. QA territoriais/Inhambane/programas separados. Limites e decisões em outputs/investmoz-disponibilizacao-integral-20261019/PROPOSTA-INTEGRAL-PARA-DECISAO.md. | Execução autorizada fdcb31f1b5b9 concluída em teste-investidor: Sectores e duplicação visual=Disponível; Legado — conteúdo restante=Instalado mas desabilitado. 1080 hashes iguais, schema171/88, custódia/scan/recuperação reais. Sem publicação ou papéis novos. Vínculo dossier legítimo pendente; incrementos QA separados. Limites em outputs/investmoz-disponibilizacao-integral-20261019/RESULTADO-DISPONIBILIZACAO-INTEGRAL.md; não encerra critérios globais não demonstrados.
[UTILIZACAO-HOMOLOGACAO-20261019] Leitura nominal de contas/recursos no destino; saldo18/10; prévia29 sem escrita; comparação de hashes QA separados. outputs/investmoz-disponibilizacao-integral-20261019/UTILIZACAO-EFECTIVA-HOMOLOGACAO.md
diff --git a/resources/js/lib/investor-context.ts b/resources/js/lib/investor-context.ts
index 57339427..d0e13266 100644
--- a/resources/js/lib/investor-context.ts
+++ b/resources/js/lib/investor-context.ts
@@ -34,6 +34,7 @@ export type ContextReference = {
version: number | string | null;
sha256: string;
fields: Record;
+ analysis?: {documented_sector?: string | null; documented_location?: string | null; [key:string]:unknown};
documents?: ContextDocument[];
visibility?: 'private' | 'public';
state?: string | null;
@@ -63,7 +64,7 @@ export type DossierContext = {
revision: number;
selection: Partial<
Record<
- 'opportunity' | 'sector' | 'territory' | 'park',
+ 'portfolio' | 'opportunity' | 'sector' | 'territory' | 'park',
ContextReference
>
>;
diff --git a/resources/js/lib/project-dossier-report.ts b/resources/js/lib/project-dossier-report.ts
index 022d463a..b9bdb33d 100644
--- a/resources/js/lib/project-dossier-report.ts
+++ b/resources/js/lib/project-dossier-report.ts
@@ -285,6 +285,7 @@ function makeSections(
);
if (context.version === 1) {
const section = sections.get('sources');
+ if (context.portfolio_origin) section?.rows.push({field:'Projecto ou carteira de origem', value:context.portfolio_origin.title, origin:`${context.portfolio_origin.key}; versão ${context.portfolio_origin.version}; ${context.portfolio_origin.href}`, classification:'Origem documental; localização e oferta não presumidas'});
if (context.consumer_opportunity) section?.rows.push({field:'Oportunidade em tratamento', value:context.consumer_opportunity, origin:context.opportunity_choices?.[0]?.opportunity?.title ?? 'Escolha guardada no dossier', classification:'Âmbito desta análise'});
for (const step of context.path?.steps ?? []) {
if (step.applicability === 'not_needed_for_preparation') section?.paragraphs.push(`${step.code} — preparação não necessária neste âmbito: ${step.reason || 'Decisão guardada do promotor'}. Histórico conservado; não constitui dispensa legal.`);
diff --git a/resources/js/lib/search-territory.ts b/resources/js/lib/search-territory.ts
index 88419519..794365c8 100644
--- a/resources/js/lib/search-territory.ts
+++ b/resources/js/lib/search-territory.ts
@@ -1,6 +1,15 @@
const levels = ['province_id', 'district_id', 'admin_post_id', 'locality_id'];
const searchRoutes = ['/carteira', '/oportunidades', '/zonas', '/educacao'];
+/** Keep search geography explicit; a documentary origin is never an invented offer. */
+export function portfolioPreparationHref(id: string, pageUrl: string): string {
+ const source = new URL(pageUrl, 'https://portal.invalid');
+ const inherited = source.searchParams.has('catalogue_query') ? new URLSearchParams(source.searchParams.get('catalogue_query')!) : source.searchParams;
+ const query = new URLSearchParams({source: `portfolio:${id}`});
+ for (const field of levels) if (inherited.get(field)) query.set(field, inherited.get(field)!);
+ return '/investimentos/iniciar?' + query.toString();
+}
+
/** Preserve an explicit complementary selection while consulting its canonical public fiche. */
export function complementPreparationHref(pageUrl: string, target?: string): string | null {
const params = new URL(pageUrl, 'https://portal.invalid').searchParams;
diff --git a/resources/js/pages/investment/submission.tsx b/resources/js/pages/investment/submission.tsx
index 608d994f..fd0fbf14 100644
--- a/resources/js/pages/investment/submission.tsx
+++ b/resources/js/pages/investment/submission.tsx
@@ -82,6 +82,7 @@ type Props = {
version: number;
payload: Partial;
opportunity_id?: number | null;
+ dossier_id?: string | null;
status: string;
};
references: References;
@@ -395,6 +396,7 @@ function Editor({
dossier. Associar reutiliza o contexto autorizado;
campos já editados conservam-se.
+ {s.dossier_id && Preparar investimento com a ficha de origem. A manifestação ficará ligada ao dossier que escolher.
}
Dossier autorizado para esta manifestação
;
entryComplements?: Complement[];
+ entrySubmission?: {id:string;version:number} | null;
}) {
const [chosen, setChosen] = useState('');
const [title, setTitle] = useState(entryComplements[0]?.kind === 'need' ? `Preparação de ${entryComplements[0].title} — ${entryComplements[0].origin.title}`.slice(0,200) : source?.title ?? opportunityChoices[0]?.opportunity.title ?? '');
@@ -28,6 +30,13 @@ export default function ContextStart({
const [key] = useState(createOperationKey);
const sourceSuffix = opportunityChoices.length ? '?' + opportunityChoices.map(c => `opportunities[]=${encodeURIComponent(c.opportunity.id)}`).join('&') : source ? '?source=' + encodeURIComponent(source.key) : '';
const suffix = sourceSuffix || Object.keys(entryQuery).length ? (sourceSuffix || '?')+(sourceSuffix ? '&' : '')+'selection_key='+encodeURIComponent(key)+'&'+new URLSearchParams(entryQuery).toString() : '';
+ const continueIn = async (id: string) => {
+ if (entrySubmission) {
+ const view = await contextApi<{case:{version:number}}>(`/investimentos/${id}/contexto`);
+ await contextApi(`/investidor/manifestacoes/${entrySubmission.id}/contexto`, {case_id:id,case_version:view.case.version,version:entrySubmission.version});
+ }
+ window.location.assign(`/investimentos/${id}/contexto/editar${suffix}`);
+ };
return (
@@ -44,9 +53,11 @@ export default function ContextStart({
{source.title}
+ {source.kind === 'portfolio' && Sector documentado: {source.analysis?.documented_sector ?? 'Por definir'}. Cobertura documental: {source.analysis?.documented_location ?? 'Por definir'}. Confirme o enquadramento e a localização do seu investimento no dossier.
}
)}
+ {entrySubmission && Ao continuar, esta manifestação será associada ao dossier escolhido, conservando a ficha de origem. Nenhum pedido será submetido.
}
Continuar um dossier existente
@@ -65,20 +76,23 @@ export default function ContextStart({
))}
- {chosen && (
- {
+ if (step && !source && !opportunityChoices.length) {window.location.assign(`/investimentos/${chosen}#${step}`);return;}
+ setBusy(true);setError('');void continueIn(chosen).catch(e=>{setError(e.message);setBusy(false);});
+ }}
>
{step && !source && !opportunityChoices.length
? 'Abrir ' + step + ' no mesmo dossier'
: 'Preparar neste dossier'}
-
+
)}
+ {chosen && !entrySubmission &&
+ {step && !source && !opportunityChoices.length ? 'Abrir ' + step + ' no mesmo dossier' : 'Preparar neste dossier'}
+ }
Se já preparou este investimento, continue nele. Não é
necessário criar outro dossier.
@@ -95,11 +109,7 @@ export default function ContextStart({
client_key: key,
reuse_consent: consent,
})
- .then((r) =>
- window.location.assign(
- `/investimentos/${r.id}/contexto/editar${suffix}`,
- ),
- )
+ .then((r) => continueIn(r.id))
.catch((e) => setError(e.message))
.finally(() => setBusy(false));
}}
diff --git a/resources/js/pages/investor-path/context.tsx b/resources/js/pages/investor-path/context.tsx
index 3153c396..6f4978f5 100644
--- a/resources/js/pages/investor-path/context.tsx
+++ b/resources/js/pages/investor-path/context.tsx
@@ -30,7 +30,7 @@ type Options = {
parks: { id: string; name: string; version_no: number }[];
search_limited: boolean;
};
-type Slot = 'opportunity' | 'sector' | 'territory' | 'park';
+type Slot = 'portfolio' | 'opportunity' | 'sector' | 'territory' | 'park';
export default function ContextEditor({
initial,
options: initialOptions,
@@ -41,6 +41,7 @@ export default function ContextEditor({
entrySources = [],
entryLocationDifferences = [],
entryComplements = [],
+ entryTerritory = null,
}: {
initial: ContextView;
options: Options;
@@ -49,6 +50,7 @@ export default function ContextEditor({
requestedChoices?: OpportunityChoice[] | null;
entrySources?: string[];
entryComplements?: Complement[];
+ entryTerritory?: ContextReference | null;
entryLocationDifferences?: {title:string;saved:string;requested:string}[];
draft?: {draft_sequence?:number;needs_review?:boolean;selection?:Partial>;declarations?:Record;replace_fields?:string[];document_links?:Record}|null;
}) {
@@ -81,12 +83,12 @@ export default function ContextEditor({
const [options, setOptions] = useState(initialOptions);
const [query, setQuery] = useState('');
const [changes, setChanges] = useState>>(() =>
- draft?.selection ?? (source
+ ({...(draft?.selection ?? {}), ...(entryTerritory && !draft?.selection?.territory && !initial.context.selection.territory ? {territory: entryTerritory.key} : {}), ...(source?.kind === 'portfolio' ? {portfolio: source.key} : draft?.selection ? {} : source
? {
[source.kind === 'business' ? 'opportunity' : source.kind]:
source.key,
}
- : {}),
+ : {})}),
);
const [declarations, setDeclarations] = useState>(
draft?.declarations ?? {},
@@ -311,6 +313,11 @@ export default function ContextEditor({
{draft?.needs_review&&O rascunho foi recuperado, mas o dossier recebeu outras alterações. Reveja os dados antes de confirmar.
}
{draftStatus.startsWith('Rascunho não guardado')&&setDraftRetry(v=>v+1)}>Tentar guardar novamente }
{setChoices(next);setManageChoices(true);setPlan(null);}}/>
+ {(changes.portfolio || view.context.selection.portfolio) &&
+ Origem documental: {source?.kind === 'portfolio' ? source.title : view.context.selection.portfolio?.title} .
+ {' '}A ficha é conservada como origem. Escolha o sector e a localização do investimento abaixo; a cobertura documental não é uma implantação atribuída.
+
}
+ {entryTerritory && view.context.selection.territory && entryTerritory.key !== view.context.selection.territory.key && A pesquisa indicava {entryTerritory.title}. Conservou-se a localização guardada, {view.context.selection.territory.title}; pode alterá-la explicitamente abaixo e conferir os impactos.
}
{view.context.revision > 0 && !Object.keys(changes).length && JSON.stringify(choices) === JSON.stringify(view.context.opportunity_choices ?? []) && }
Acrescentar uma oportunidade à escolha{const o=options.opportunities.find(o=>o.key===e.target.value);if(o && !choices.some(c=>c.opportunity.key===o.key)){setChoices([...choices,{opportunity:{...o,id:o.key.split(':')[1],href:'/oportunidades',version:null,sha256:'',fields:{}},territory:null,location_reason:'',location_state:'undetermined'}]);setManageChoices(true);setPlan(null);}}}>Seleccionar ficha {options.opportunities.filter(o=>o.kind==='opportunity'&&!choices.some(c=>c.opportunity.key===o.key)).map(o=>{o.title} )}
diff --git a/resources/js/pages/investor-path/show.tsx b/resources/js/pages/investor-path/show.tsx
index e45ab013..b82486d6 100644
--- a/resources/js/pages/investor-path/show.tsx
+++ b/resources/js/pages/investor-path/show.tsx
@@ -444,6 +444,10 @@ export default function InvestmentPath(path: Path) {
Os meus investimentos
{path.case.title}
+ {path.investment_context?.selection.portfolio &&
+ Origem documental: {path.investment_context.selection.portfolio.title}.
+ {' '}A localização do investimento é escolhida no contexto.
+
}
{!!path.opportunity_options?.length && Oportunidade em tratamento
router.get(`/investimentos/${path.case.id}`, event.target.value ? {opportunity:event.target.value} : {}, {preserveState:false})}>
Escolha a oportunidade
diff --git a/resources/js/pages/portfolio/index.tsx b/resources/js/pages/portfolio/index.tsx
index 1d3ea2f0..e412c492 100644
--- a/resources/js/pages/portfolio/index.tsx
+++ b/resources/js/pages/portfolio/index.tsx
@@ -14,12 +14,15 @@ export default function Index({
management,
filters,
territorySelection = [],
+ sectors = [],
}: {
records: Paginated;
management: boolean;
+ sectors?: string[];
filters: {
q?: string;
kind?: string;
+ sector?: string;
province_id?: string;
district_id?: string;
admin_post_id?: string;
@@ -30,6 +33,7 @@ export default function Index({
const form = useForm({
q: filters.q ?? '',
kind: filters.kind ?? '',
+ sector: filters.sector ?? '',
province_id: filters.province_id ?? '',
district_id: filters.district_id ?? '',
admin_post_id: filters.admin_post_id ?? '',
@@ -77,6 +81,12 @@ export default function Index({
Projectos âncora
+
+ form.setData('sector', e.target.value)}>
+ Todos os sectores
+ {sectors.map((sector) => {sector} )}
+
+
diff --git a/resources/js/pages/portfolio/show.tsx b/resources/js/pages/portfolio/show.tsx
index 287c778e..6d1a5104 100644
--- a/resources/js/pages/portfolio/show.tsx
+++ b/resources/js/pages/portfolio/show.tsx
@@ -1,7 +1,7 @@
import { Link, useForm, router, usePage } from '@inertiajs/react';
import { useState } from 'react';
import { catalogueReturnHref } from '@/lib/catalogue-context';
-import { searchTerritoryHref } from '@/lib/search-territory';
+import { searchTerritoryHref, portfolioPreparationHref } from '@/lib/search-territory';
import InvestmentMapPanel from '@/components/investment-map-panel';
import StructureGeographyPanel, {
type StructureGeography,
@@ -94,6 +94,14 @@ function Editor({
{kind(record)} · {record.content.code}
Fonte: {record.source}
+ {!management && (
+
+
+ Preparar investimento a partir desta ficha
+
+
A ficha acompanha o dossier como origem documental. A localização do investimento e as ofertas associadas são escolhas próprias.
+
+ )}
{(record.project_id || record.cluster_id) && (
+ { const query = new URL(pageUrl, 'https://portal.invalid').searchParams.get('catalogue_query'); return query ? '?catalogue_query=' + encodeURIComponent(query) : ''; })()}>
Entrar
diff --git a/routes/web.php b/routes/web.php
index b99eb676..7e4ccef7 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -92,6 +92,7 @@ Route::middleware(['auth', 'verified', \App\Http\Middleware\EnsureDocumentManage
Route::get('/artigos/{id}', [\App\Http\Controllers\EditorialArticleController::class, 'show'])->whereNumber('id')->name('editorial.show');
Route::get('/carteira', [InvestmentPortfolioController::class, 'index'])->name('portfolio.index');
Route::get('/carteira/{id}', [InvestmentPortfolioController::class, 'show'])->whereUuid('id')->name('portfolio.show');
+Route::get('/carteira/{id}/interesse', [InvestmentPortfolioController::class, 'resumeInterest'])->whereUuid('id')->middleware(['auth', \App\Http\Middleware\VerifiedOrSimpleParticipation::class])->name('portfolio.interest');
Route::get('/oportunidades', [InvestmentDiscoveryController::class, 'index'])->name('portal.opportunities');
Route::get('/oportunidades/{slug}', [InvestmentDiscoveryController::class, 'detail'])->name('portal.opportunity');
Route::get('/negocios', [PublicBusinessOpportunityController::class, 'index'])->name('business-marketplace.index');
diff --git a/tests/Feature/InvestmentAnchorIntegrationTest.php b/tests/Feature/InvestmentAnchorIntegrationTest.php
new file mode 100644
index 00000000..343370ba
--- /dev/null
+++ b/tests/Feature/InvestmentAnchorIntegrationTest.php
@@ -0,0 +1,127 @@
+assertSame('simulator_fiscal_delta_20261021_test', $identity->name);
+ $this->assertSame(55441, (int) $identity->port);
+ $this->withoutVite();
+ $this->withoutMiddleware(ThrottleRequests::class);
+ config(['investor-path.enabled' => true, 'investor-path.private_preparation' => true, 'suitecrm.enabled' => false, 'investmoz_ai.enabled' => false]);
+ $this->actor = User::factory()->create();
+ }
+
+ public function test_documented_sector_filter_is_explicit_and_preserves_the_catalogue_scope(): void
+ {
+ $anchor = InvestmentPortfolioController::visible()->where('content->code', 'A06')->firstOrFail();
+ $sector = $anchor->content['sector'];
+ $this->get('/carteira?'.http_build_query(['kind' => 'project', 'sector' => $sector]))->assertOk()
+ ->assertInertia(fn (Assert $p) => $p->where('filters.sector', $sector)->has('records.data', 1)->where('records.data.0.id', $anchor->id)->has('sectors'));
+ $this->get('/carteira?sector=sector-inexistente')->assertOk()->assertInertia(fn (Assert $p) => $p->has('records.data', 0));
+ $this->get('/carteira')->assertOk()->assertInertia(fn (Assert $p) => $p->where('records.total', InvestmentPortfolioController::visible()->count()));
+ }
+
+ public function test_accepted_territories_are_recovered_by_identity_with_citations_and_idempotence(): void
+ {
+ $service = app(ApprovedAnchorTerritories::class);
+ $before = DB::table('investment_dossiers')->orderBy('id')->get()->toJson();
+ $plan = $service->plan();
+ $this->assertCount(28, $plan['links']);
+ $this->assertCount(13, $plan['projects']);
+ $result = $service->apply($plan);
+ $this->assertSame(count(array_filter($plan['links'], fn ($link) => ! $link['already_present'])), $result['relations_restored']);
+ $this->assertSame(0, $result['publication_changes']);
+ $this->assertSame($before, DB::table('investment_dossiers')->orderBy('id')->get()->toJson());
+ $second = $service->apply($service->plan());
+ $this->assertSame(0, $second['relations_restored']);
+ $this->assertSame(0, $second['projects_updated']);
+ $anchor = InvestmentPortfolioController::visible()->where('content->code', 'A06')->firstOrFail();
+ $locations = app(InvestmentRelations::class)->projectLocations($anchor->project_id);
+ $this->assertCount(4, $locations);
+ $this->assertNotEmpty($locations[0]['source_quote']);
+ $this->assertSame('secondary', $locations[0]['role']);
+ $province = $locations[0]['id'];
+ $this->get('/carteira?'.http_build_query(['kind' => 'project', 'sector' => $anchor->content['sector'], 'province_id' => $province]))->assertOk()
+ ->assertInertia(fn (Assert $p) => $p->has('records.data', 1)->where('records.data.0.id', $anchor->id));
+ $this->assertCount(0, app(InvestmentRelations::class)->projectLocations(InvestmentPortfolioController::visible()->where('content->code', 'A01')->firstOrFail()->project_id));
+ }
+
+ public function test_anchor_without_offer_survives_login_dossier_and_simulator_as_documentary_origin(): void
+ {
+ $anchor = InvestmentPortfolioController::visible()->where('content->code', 'A06')->firstOrFail();
+ $source = 'portfolio:'.$anchor->id;
+ $entry = '/investimentos/iniciar?'.http_build_query(['source' => $source]);
+ $this->get($entry)->assertRedirect(route('login'));
+ $this->assertStringEndsWith($entry, session('url.intended'));
+ $this->actingAs($this->actor);
+ $this->get($entry)->assertOk()->assertInertia(fn (Assert $p) => $p->where('source.key', $source)->has('opportunityChoices', 0));
+ $reference = app(InvestorContext::class)->reference($source);
+ $this->assertArrayNotHasKey('province_id', $reference['fields']);
+ $this->assertFalse($reference['analysis']['available_opportunity']);
+ $id = $this->postJson('/investimentos', ['title' => 'SYNTHETIC QA - ideia propria', 'client_key' => (string) Str::uuid(), 'reuse_consent' => true])->assertCreated()->json('id');
+ $body = ['version' => $this->getJson('/investimentos/'.$id.'/contexto')->json('case.version'), 'selection' => ['portfolio' => $source]];
+ $preview = $this->postJson('/investimentos/'.$id.'/contexto/previa', $body)->assertOk()->json();
+ $this->assertSame('SYNTHETIC QA - ideia propria', $preview['fields']['project_title']);
+ $this->postJson('/investimentos/'.$id.'/contexto/confirmar', [...$body, 'preview_hash' => $preview['preview_hash'], 'operation_key' => (string) Str::uuid(), 'confirm' => true])->assertOk();
+ $view = $this->getJson('/investimentos/'.$id.'/contexto')->assertOk()->json();
+ $this->assertSame($source, $view['context']['selection']['portfolio']['key']);
+ $this->assertSame([], $view['context']['opportunity_choices']);
+ $snapshot = json_decode($view['prefill']['simulator']['context_applicability_snapshot'], true);
+ $this->assertSame($source, $snapshot['portfolio_origin']['key']);
+ $draft = $this->postJson('/api/v1/simulation-drafts', ['context' => $id, 'personal_snapshot' => [], 'economic_snapshot' => ['purpose' => 'simulate_only', 'project_title' => 'SYNTHETIC QA - titulo proprio', 'context_applicability_snapshot' => json_encode($snapshot)]], ['Idempotency-Key' => (string) Str::uuid()])->assertCreated()->json('data.id');
+ $saved = $this->getJson('/api/v1/simulation-drafts/'.$draft.'?context='.$id)->assertOk()->json('data.economic_snapshot');
+ $this->assertSame($source, json_decode($saved['context_applicability_snapshot'], true)['portfolio_origin']['key']);
+ $this->assertSame('SYNTHETIC QA - titulo proprio', $saved['project_title']);
+ $anchor->publication_status = 'draft';
+ $anchor->save();
+ $this->get($entry)->assertNotFound();
+ }
+
+ public function test_interest_resumption_keeps_the_same_anchor_and_filters_without_creating_a_request_on_get(): void
+ {
+ $anchor = InvestmentPortfolioController::visible()->where('content->code', 'A06')->firstOrFail();
+ $query = http_build_query(['sector' => $anchor->content['sector'], 'kind' => 'project']);
+ $entry = '/carteira/'.$anchor->id.'/interesse?'.http_build_query(['catalogue_query' => $query]);
+ $before = DB::table('investment_submissions')->count();
+ $this->get($entry)->assertRedirect(route('login'));
+ $this->assertStringEndsWith($entry, session('url.intended'));
+ $this->actingAs($this->actor);
+ $this->get($entry)->assertRedirect('/carteira/'.$anchor->id.'?'.http_build_query(['catalogue_query' => $query, 'prepare_interest' => '1']));
+ $this->assertSame($before, DB::table('investment_submissions')->count());
+ $response = $this->postJson('/investidor/manifestacoes', ['dossier_id' => $anchor->id])->assertCreated();
+ $row = DB::table('investment_submissions')->where('id', $response->json('id'))->first();
+ $this->assertSame($anchor->id, $row->dossier_id);
+ $start = '/investimentos/iniciar?'.http_build_query(['source' => 'portfolio:'.$anchor->id, 'submission' => $row->id]);
+ $this->get($start)->assertOk()->assertInertia(fn (Assert $p) => $p->where('entrySubmission.id', $row->id)->where('entrySubmission.version', (int) $row->version));
+ $other = InvestmentPortfolioController::visible()->where('id', '!=', $anchor->id)->firstOrFail();
+ $this->get('/investimentos/iniciar?'.http_build_query(['source' => 'portfolio:'.$other->id, 'submission' => $row->id]))->assertUnprocessable();
+ $case = $this->postJson('/investimentos', ['title' => 'SYNTHETIC QA - manifesto e ancora', 'client_key' => (string) Str::uuid(), 'reuse_consent' => true])->assertCreated()->json('id');
+ $version = $this->getJson('/investimentos/'.$case.'/contexto')->json('case.version');
+ $this->postJson('/investidor/manifestacoes/'.$row->id.'/contexto', ['case_id' => $case, 'case_version' => $version, 'version' => (int) $row->version])->assertOk();
+ $this->assertSame($row->id, DB::table('desk_cases')->where('id', $case)->value('submission_id'));
+ $this->assertSame($anchor->id, DB::table('investment_submissions')->where('id', $row->id)->value('dossier_id'));
+ $this->actingAs(User::factory()->create());
+ $this->get($start)->assertNotFound();
+ }
+}
diff --git a/tests/frontend/anchor-integration.test.mjs b/tests/frontend/anchor-integration.test.mjs
new file mode 100644
index 00000000..a18057b3
--- /dev/null
+++ b/tests/frontend/anchor-integration.test.mjs
@@ -0,0 +1,24 @@
+import test from 'node:test';
+import assert from 'node:assert/strict';
+import { portfolioPreparationHref } from '../../resources/js/lib/search-territory.ts';
+import { createProjectDossierReport } from '../../resources/js/lib/project-dossier-report.ts';
+
+test('anchor preparation keeps exact identity and explicit search geography', () => {
+ const query = new URLSearchParams({sector:'Agro-indústria e agricultura',province_id:'province-1',district_id:'district-1'});
+ const href = portfolioPreparationHref('anchor-1','/carteira/anchor-1?catalogue_query='+encodeURIComponent(query.toString()));
+ const params = new URL(href,'https://portal.invalid').searchParams;
+ assert.equal(params.get('source'),'portfolio:anchor-1');
+ assert.equal(params.get('province_id'),'province-1');
+ assert.equal(params.get('district_id'),'district-1');
+ assert.equal(params.has('opportunity'),false);
+ assert.equal(params.has('sector_id'),false);
+});
+
+test('report identifies the saved documentary anchor without asserting an available offer', () => {
+ const context = {version:1,portfolio_origin:{key:'portfolio:anchor-1',title:'Âncora documental',version:2,href:'/carteira/anchor-1'}};
+ const report = createProjectDossierReport({context_applicability_snapshot:JSON.stringify(context)},{selectedSections:new Set(['sources'])});
+ const row = report.sections.find(section=>section.id==='sources').rows.find(row=>row.field==='Projecto ou carteira de origem');
+ assert.equal(row.value,'Âncora documental');
+ assert.match(row.origin,/portfolio:anchor-1; versão 2/);
+ assert.match(row.classification,/localização e oferta não presumidas/);
+});
diff --git a/tools/restore-approved-anchor-territories.php b/tools/restore-approved-anchor-territories.php
new file mode 100644
index 00000000..48512ca8
--- /dev/null
+++ b/tools/restore-approved-anchor-territories.php
@@ -0,0 +1,71 @@
+make(Kernel::class)->bootstrap();
+$args = getopt('', ['qa', 'apply', 'output:', 'preview-sha256:', 'backup:']);
+$qa = isset($args['qa']);
+$apply = isset($args['apply']);
+$expected = $qa ? 'simulator_fiscal_delta_20261021_test' : 'teste_investidor';
+$port = $qa ? 55441 : 5432;
+$identity = DB::selectOne('select current_database() as name,inet_server_port() as port');
+if ($identity->name !== $expected || (int) $identity->port !== $port) {
+ throw new RuntimeException('Named isolated QA or homologation required.');
+}
+if (! $qa && (! getenv('SSH_CONNECTION') || ! function_exists('posix_geteuid') || posix_geteuid() !== 0 || rtrim(config('app.url'), '/') !== 'https://teste-investidor.tempo.co.mz')) {
+ throw new RuntimeException('Authenticated destination operator required.');
+}
+$output = $args['output'] ?? '';
+if (! $output || is_file($output) || str_contains(str_replace('\\', '/', $output), '/public/')) {
+ throw new RuntimeException('New private receipt path required.');
+}
+$service = app(ApprovedAnchorTerritories::class);
+DB::beginTransaction();
+try {
+ DB::statement($apply ? 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE' : 'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY');
+ if ($apply) {
+ DB::select('select pg_advisory_xact_lock(231026,28)');
+ }
+ $plan = $service->plan();
+ $hash = hash('sha256', json_encode([$expected, $plan], JSON_THROW_ON_ERROR));
+ $result = ['mode' => $apply ? 'applied' : 'preview', 'database' => $expected, 'port' => $port, 'qa' => $qa, 'manifest_sha256' => ApprovedAnchorTerritories::HASH, 'preview_sha256' => $hash, 'relations' => count($plan['links']), 'projects' => count($plan['projects'])];
+ if ($apply) {
+ if (! hash_equals($hash, $args['preview-sha256'] ?? '')) {
+ throw new RuntimeException('Destination changed after preview.');
+ }
+ if (! $qa) {
+ $directory = $args['backup'] ?? '';
+ $backup = json_decode(file_get_contents($directory.'/backup-receipt.json'), true, 512, JSON_THROW_ON_ERROR);
+ $restore = json_decode(file_get_contents($directory.'/restore-receipt.json'), true, 512, JSON_THROW_ON_ERROR);
+ if (! $restore['restore_verified'] || $backup['target']['database'] !== $expected || (int) $backup['target']['port'] !== $port
+ || ! hash_equals($backup['sha256'], $restore['source_dump_sha256']) || ! hash_equals($backup['sha256'], hash_file('sha256', $backup['dump_path']))) {
+ throw new RuntimeException('Matching backup and isolated restoration required.');
+ }
+ }
+ file_put_contents($output.'.before.json', json_encode($plan, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR));
+ if (! $qa) {
+ chmod($output.'.before.json', 0600);
+ }
+ $result += $service->apply($plan);
+ DB::commit();
+ } else {
+ DB::rollBack();
+ }
+ file_put_contents($output, json_encode([...$result, 'plan' => $plan], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR));
+ if (! $qa) {
+ chmod($output, 0600);
+ }
+ echo json_encode($result, JSON_THROW_ON_ERROR);
+} catch (Throwable $error) {
+ if (DB::transactionLevel()) {
+ DB::rollBack();
+ }
+ throw $error;
+}