State Model - AFPS Tracker

Confirmed logical domain model for the approved AFPS Tracker first repo read-through. The canonical domain model and model-tree manifest have been written, the flow-tree branches are attached to the model, approved glossary terms were appended, and the working cursor was archived.

Statusconfirmedapproved 2026-07-02
Topicafps-tracker
Product Pathresearch/afps-tracker
Next Route$ux-variations uf-orient-portfolio

Decision Summary

Approval result: the logical model is approved as the AFPS Tracker substrate for UX variation work. The model is coherent across all five framework passes and keeps AFPS Tracker read-first, source-native, and subordinate to canonical AFPS artifacts.

Primary aggregateProductPath owns selected-path interpretation, source-backed claims, evidence, provenance, diagnostics, and handoff eligibility.
Thin portfolio rootPortfolioSnapshot and path refs support orientation and unresolved/excluded path visibility without making repo scan the central aggregate.
Trust spineTrustEnvelope preserves trust level, parser confidence, source confidence, warnings, and diagnostic refs separately.
Boundary ruleInactive, promoted, out-of-scope, unsupported, contradicted, and blocked states suppress normal next-command routing.

Framework Evidence

FrameworkIntermediateDecision Contribution
Event modelingdocs/history/archive/2026-07-02/002008/design/afps-tracker/state-model-afps-tracker/event-modeling.mdTimeline of scan, manifest interpretation, selection, source resolution, diagnostics, evidence/provenance inspection, handoff generation, copy, and boundary explanation.
Domain modeldocs/history/archive/2026-07-02/002008/design/afps-tracker/state-model-afps-tracker/domain-model.mdDDD spine with ProductPath as the main aggregate root and Portfolio as a thin orientation aggregate.
State machinedocs/history/archive/2026-07-02/002008/design/afps-tracker/state-model-afps-tracker/state-machine.mdLifecycles for portfolio, product path, source artifact, evidence link, provenance record, diagnostic issue, and handoff summary.
Data modeldocs/history/archive/2026-07-02/002008/design/afps-tracker/state-model-afps-tracker/data-model.mdLogical ERD, attributes, relationships, read models, and integrity rules, including explicit unresolved refs.
Contract mapdocs/history/archive/2026-07-02/002008/design/afps-tracker/state-model-afps-tracker/contract-map.mdLogical command/query contracts and response shapes with trust envelopes, diagnostic refs, and boundary suppression.

Confirmed Domain Model

The following content was written to design/afps-tracker/domain-model-afps-tracker.md after compiled YAML approval.

---
skill: state-model
status: confirmed
topic: afps-tracker
product_path: research/afps-tracker
source_command: "$state-model afps-tracker"
flow_tree: design/afps-tracker/flow-tree-afps-tracker.yaml
model_tree: design/afps-tracker/model-tree-afps-tracker.yaml
alignment_page: alignment/state-model-afps-tracker.html
---

# AFPS Tracker Domain Model

## Scope

This logical model defines the entities, value objects, state machines, events, commands, read models, policies, and contracts for the approved AFPS Tracker first repo read-through. The model is anchored to the approved flow-tree nodes:

- `uf-orient-portfolio`
- `uf-verify-selected-path`
- `uf-inspect-source-provenance`
- `uf-recover-diagnostics`
- `uf-handoff-resume`
- `uf-explain-boundaries`

AFPS Tracker remains read-first and source-native. Canonical truth stays in AFPS workflow artifacts: `research/.progress.yaml`, scoped research documents, alignment pages, canonical design artifacts, archive snapshots, and working packets where relevant. This model does not define storage, real endpoints, URLs, auth, migrations, indexes, deployment, file watchers, or runtime mechanics.

## Ubiquitous-Language Glossary

| Term | Meaning |
| --- | --- |
| Repository context | Logical context for one repo-local AFPS read-through. |
| Portfolio snapshot | Source-derived grouping of active, parallel, inactive, excluded, and unresolved product paths for a scan. |
| Portfolio path ref | A source active/excluded/unresolved path reference, whether or not it resolves to a ProductPath. |
| Product path | A source-derived AFPS research/product path interpreted from canonical AFPS artifacts. |
| Source artifact | A canonical AFPS file or generated artifact used as evidence, provenance, diagnostics, or handoff source. |
| Source-backed claim | A displayed or handoffable assertion whose support must be traceable or explicitly caveated. |
| Evidence link | Logical link from a claim to a source artifact, field, section, approval record, or source hint. |
| Provenance record | Approval, canonicalization, amendment, archive, review, or working-packet lineage. |
| Diagnostic issue | Trust degradation or recovery item affecting source, claim, path, portfolio, or handoff level. |
| Trust envelope | Response wrapper carrying trust level, parser confidence, source confidence, warnings, and diagnostic refs. |
| Parser confidence | Confidence in extraction or mapping from a source artifact. |
| Source confidence | Confidence that the underlying source/provenance supports the claim. |
| Handoff eligibility | Derived availability of clean, warning, blocked, explanatory, promoted-boundary, or out-of-scope output. |
| Boundary kind | Why a path or request cannot produce normal active AFPS routing. |
| Next-command suppression | Explicit suppression of normal next-command output under blocked, promoted, inactive, contradicted, unsupported, or out-of-scope states. |

## Entities And Value Objects

| Element | Kind | Key attributes | Relationships | Flow bindings |
| --- | --- | --- | --- | --- |
| RepositoryContext | entity | repository_ref, scan_started_at, scan_completed_at, scan_state, source_health, warnings | Owns zero-or-one PortfolioSnapshot and discovered source artifacts/diagnostics for the read-through. | `uf-orient-portfolio` triggers/displays; `uf-recover-diagnostics` displays |
| PortfolioSnapshot | aggregate-root | snapshot_id, repository_ref, progress_manifest_ref, snapshot_state, active_path_refs, excluded_path_refs, parser_confidence, source_confidence | Has many PortfolioPathRefs and ProductPaths. | `uf-orient-portfolio` reads/displays; `uf-explain-boundaries` reads; `uf-recover-diagnostics` transitions |
| PortfolioPathRef | entity | path_ref_id, path_id, scope_path, source_status, resolution_state, boundary_kind, diagnostic_refs | Resolves to zero-or-one ProductPath and may raise diagnostics. | `uf-orient-portfolio` displays; `uf-explain-boundaries` displays; `uf-recover-diagnostics` writes |
| ProductPath | aggregate-root | path_id, label, scope_path, source_status, pipeline_stage, reason, next_skill, path_state, trust_level, handoff_eligibility, boundary_kind | Owns source artifacts, claims, provenance, diagnostics, and handoff summaries. | `uf-orient-portfolio`, `uf-verify-selected-path`, `uf-handoff-resume`, `uf-explain-boundaries` |
| SourceArtifact | entity | artifact_id, artifact_ref, artifact_kind, source_role, read_status, approval_status, freshness_state, parser_confidence, source_confidence, warnings | Supports claims and provenance; can raise diagnostics. | `uf-verify-selected-path`, `uf-inspect-source-provenance`, `uf-recover-diagnostics` |
| SourceBackedClaim | entity | claim_id, path_id, claim_kind, claim_text, support_status, parser_confidence, source_confidence, trust_level, derived_from, warnings | Has zero-or-many EvidenceLinks and Diagnostics. | `uf-verify-selected-path`, `uf-inspect-source-provenance`, `uf-recover-diagnostics`, `uf-handoff-resume` |
| EvidenceLink | entity | evidence_link_id, claim_id, evidence_ref, resolved_ref, resolution_state, support_status, read_status, source_hint, warnings | Links a claim to zero-or-one resolved SourceArtifact. | `uf-inspect-source-provenance`, `uf-recover-diagnostics` |
| ProvenanceRecord | entity | provenance_id, path_id, provenance_ref, provenance_kind, approval_state, decision_summary, canonical_target, archive_refs, confidence, warnings | Supports claims, artifacts, and handoff confidence. | `uf-inspect-source-provenance`, `uf-recover-diagnostics`, `uf-handoff-resume` |
| DiagnosticIssue | entity | issue_id, issue_kind, severity, level, state, affected_refs, affected_claims, affected_paths, handoff_impact, recommended_manual_check | Attaches at the narrowest source, claim, path, portfolio, or handoff level. | `uf-recover-diagnostics`, `uf-orient-portfolio`, `uf-handoff-resume` |
| HandoffSummary | entity/read-model output | summary_id, path_id, handoff_type, copy_state, confidence, next_skill, branch_state_explanation, handoff_boundary, included refs, blocked_reasons | Reads path, claims, evidence, provenance, and diagnostics; may be copied only when policies permit. | `uf-handoff-resume`, `uf-explain-boundaries` |
| ArtifactRef | value-object | path, section_hint, artifact_kind, source_role | Used by source, evidence, provenance, and diagnostics. | `uf-verify-selected-path`, `uf-inspect-source-provenance` |
| TrustLevel | value-object | clean, warning, blocked, partial, inferred, unsupported, contradicted, source-backed, explanatory, out-of-scope | Used by paths, claims, diagnostics, and handoffs. | `uf-recover-diagnostics`, `uf-handoff-resume` |
| ParserConfidence | value-object | high, medium, low, unknown, rationale | Kept separate from source confidence. | `uf-orient-portfolio`, `uf-verify-selected-path`, `uf-recover-diagnostics` |
| SourceConfidence | value-object | confirmed, partial, review-only, unsupported, contradicted, missing, unknown | Kept separate from parser confidence. | `uf-inspect-source-provenance`, `uf-recover-diagnostics`, `uf-handoff-resume` |
| HandoffEligibility | value-object | clean-copy, warning-copy, blocked, explanatory, promoted-boundary, out-of-scope, unavailable | Derived by policy from path state, trust, diagnostics, and boundary kind. | `uf-handoff-resume`, `uf-explain-boundaries` |
| BoundaryKind | value-object | inactive, archived, deferred, revisit-candidate, promoted, out-of-scope, unsupported, unresolved | Suppresses normal active routing. | `uf-explain-boundaries`, `uf-handoff-resume` |

## State Machines

### PortfolioSnapshot

States: `unscanned`, `scanning`, `no-afps-state`, `manifest-malformed`, `paths-discovered`, `partial`, `source-backed`, `blocked`.

Key transitions: `ScanPortfolio` moves `unscanned -> scanning`; missing source moves to `no-afps-state`; malformed manifest moves to `manifest-malformed`; discovered paths move to `paths-discovered`; unresolved refs or non-blocking diagnostics move to `partial`; classified clean source state moves to `source-backed`; blocking portfolio diagnostics move to `blocked`.

UI mappings: empty/no-manifest overview, loading portfolio overview, grouped path rows, partial/warning badges, blocking portfolio diagnostic, clean portfolio overview.

### ProductPath

States: `undiscovered`, `discovered`, `selected`, `source-inventorying`, `source-backed`, `partial`, `warning`, `blocked`, `inactive`, `promoted-boundary`, `out-of-scope`.

Key transitions: discovered source record creates `discovered`; excluded or inactive source status moves to `inactive`; promoted state moves to `promoted-boundary`; selection moves to `selected`; source inventory moves to `source-inventorying`; supported claims move to `source-backed`; unresolved non-core support moves to `partial`; warning diagnostics move to `warning`; contradictions, unreadable core source, malformed core source, or next-skill inconsistency move to `blocked`; out-of-scope requests move to `out-of-scope`.

UI mappings: portfolio row, selected-path loading frame, clean detail, partial detail, warning caveats, blocked detail, inactive explanation, promoted boundary explanation, out-of-scope explanation.

### SourceArtifact

States: `referenced`, `resolving`, `found`, `parsed`, `confirmed`, `review-only`, `amended`, `archived`, `missing`, `unreadable`, `malformed`, `stale`, `unsupported`.

Key transitions: source inventory or evidence resolution moves to `resolving`; readable artifacts move to `found`; parsed facts move to `parsed`; confirmed provenance moves to `confirmed`; review-state provenance moves to `review-only`; amendment or archive lineage moves to `amended` or `archived`; missing, permission, malformed, stale, or unsupported support moves to the corresponding diagnostic state.

### EvidenceLink

States: `unresolved`, `resolving`, `resolved`, `supports-claim`, `partially-supports-claim`, `contradicts-claim`, `inaccessible`.

Key transitions: inspection moves unresolved links to resolving; resolved source refs move to `resolved`; claim evaluation moves to supported, partial, or contradictory support; inaccessible source preview moves to `inaccessible`; source review can return partial or contradictory links to resolving.

### ProvenanceRecord

States: `missing`, `discovered`, `review`, `confirmed`, `amended`, `archived`, `partial`, `contradicted`.

Key transitions: discovered records move to `discovered`; confirmed approval/canonical target moves to `confirmed`; unapproved review state moves to `review`; missing targets move to `missing`; amendments and archives preserve lineage; partial or contradictory provenance degrades trust and can return to discovered after source review.

### DiagnosticIssue

Severity states: `none`, `raised`, `classified`, `warning`, `blocked`, `partial`, `resolved-by-source-review`.

Affected-level dimension: `source-level`, `claim-level`, `path-level`, `portfolio-level`, `handoff-level`.

Rule: severity and affected level are separate dimensions. Diagnostics degrade trust at the narrowest affected scope first, then path and handoff levels only when needed.

### HandoffSummary

States: `unavailable`, `requested`, `clean-copy`, `warning-copy`, `blocked`, `explanatory`, `promoted-boundary`, `out-of-scope`, `copied`, `suppressed`.

Key transitions: `GenerateHandoff` moves unavailable summaries to requested; clean source-backed selected paths move to clean-copy; non-blocking warnings move to warning-copy; blocking diagnostics move to blocked; inactive, promoted, or out-of-scope states move to explanatory/boundary states; permitted copy moves to copied; blocked copy moves to suppressed.

## Events

Core events: `RepositoryScanStarted`, `ProgressManifestLocated`, `ProgressManifestMissing`, `ProgressManifestParsed`, `ProgressManifestMalformed`, `ActivePathsNormalized`, `ProductPathRecordDiscovered`, `ProductPathRecordExcluded`, `ActivePathReferenceUnresolved`, `ProductPathSelected`, `ScopedSourceInventoryStarted`, `ScopedResearchArtifactResolved`, `ScopedResearchArtifactMissing`, `EvidenceRefResolutionStarted`, `EvidenceRefResolved`, `EvidenceRefUnresolved`, `ClaimSupportEvaluated`, `ProvenanceRecordDiscovered`, `ProvenanceRecordConfirmed`, `ProvenanceRecordReviewOnly`, `ProvenanceRecordArchived`, `ProvenanceRecordMissing`, `DiagnosticIssueRaised`, `DiagnosticIssueClassified`, `TrustLevelChanged`, `HandoffEligibilityChanged`, `ClaimInspectionRequested`, `SourcePreviewPrepared`, `SourcePreviewUnavailable`, `NextSkillCandidateDetected`, `NextSkillCandidateSuppressed`, `HandoffGenerationRequested`, `HandoffSummaryPrepared`, `CleanCopyPrepared`, `WarningCopyPrepared`, `HandoffBlocked`, `HandoffCopyRequested`, `HandoffCopied`, `HandoffCopySuppressed`, `BoundaryExplanationRequested`, `PromotedBoundaryDetected`, `InactivePathExplained`, `OutOfScopeRequestExplained`.

## Commands And Queries

Commands: `ScanPortfolio`, `SelectProductPath`, `EvaluateDiagnostics`, `GenerateHandoff`, `CopyHandoff`.

Queries: `ListPortfolioPaths`, `GetSelectedPathDetail`, `InspectEvidenceRef`, `InspectProvenance`, `GetDiagnostics`, `ExplainBoundary`.

Shared logical types: `RepositoryContextInput`, `ProductPathSelector`, `ArtifactRef`, `ClaimRef`, `TrustEnvelope`, `DiagnosticRef`, `HandoffBoundary`.

Every trust-bearing response must carry `trust_level`, `parser_confidence`, `source_confidence`, `warnings[]`, and `diagnostic_refs[]`. Every claim-displaying response must carry `claim_id`, support status, evidence/provenance refs, and caveats. Boundary and handoff contracts must expose `normal_route_suppressed` and suppression reason when a next command is not safe.

## Read Models

| Read model | Source elements | Purpose |
| --- | --- | --- |
| Portfolio Overview | RepositoryContext, PortfolioSnapshot, PortfolioPathRef, ProductPath, DiagnosticIssue, SourceArtifact | Show active, parallel, inactive, excluded, unresolved, warning, and blocked portfolio state. |
| Selected Path Detail | ProductPath, SourceBackedClaim, SourceArtifact, EvidenceLink, ProvenanceRecord, DiagnosticIssue | Show selected path status, stage, reason, next skill, refs, trust, warnings, and handoff eligibility. |
| Evidence Inspector | SourceBackedClaim, EvidenceLink, SourceArtifact, DiagnosticIssue | Verify displayed claims against source support or visible unresolved/contradictory state. |
| Provenance Timeline | ProvenanceRecord, SourceArtifact, SourceBackedClaim, DiagnosticIssue | Show approval, canonicalization, amendment, archive, review, missing, partial, or contradictory provenance. |
| Diagnostics Panel | DiagnosticIssue plus affected source/claim/path/handoff refs | Show severity, affected level, handoff impact, recommended checks, and trust changes. |
| Handoff Summary | HandoffSummary, ProductPath, SourceBackedClaim, EvidenceLink, ProvenanceRecord, DiagnosticIssue | Produce clean, warning, blocked, explanatory, promoted-boundary, or out-of-scope output with caveats preserved. |

## Policies

| Policy | Rule |
| --- | --- |
| Source-backed display rule | A displayed claim can be labeled source-backed only when evidence or provenance supports it. |
| Unresolved ref preservation rule | Unresolved active refs, evidence refs, provenance refs, and source refs stay modeled with diagnostics. |
| Boundary suppression rule | Inactive, promoted, archived, deferred, revisit-candidate, unsupported, unresolved, contradicted, or out-of-scope states cannot emit normal clean next-skill handoffs. |
| Confidence separation rule | Parser confidence and source confidence are distinct and may degrade independently. |
| Narrowest diagnostic scope rule | Diagnostics attach to source, claim, path, portfolio, or handoff level at the narrowest affected level first. |
| Warning preservation rule | Warning and partial handoffs are allowed only when caveats are included in output. |
| Review-only provenance rule | Review-state pages or unconfirmed artifacts cannot support confirmed provenance claims. |
| Next-command suppression rule | Missing, contradicted, blocked, out-of-scope, or promoted-boundary next-skill values suppress normal next-command output. |

## Logical Contracts

### ScanPortfolio
Request: repository context, optional inactive/diagnostics flags, optional source refs.
Response: scan state, repository ref, portfolio snapshot ID, source health trust envelope, path counts, active/excluded/unresolved refs, diagnostics, updated read models.
Errors: no AFPS state, missing/malformed progress manifest, permission denied, partial scan, unreadable source.

### SelectProductPath
Request: repository ref, product path selector, optional portfolio snapshot ID, selection reason, detail depth.
Response: selected path ID, selection state, path state, scope path, trust envelope, source inventory status, available/blocked actions, diagnostics.
Errors: path not found, path excluded, active ref unresolved, scope path missing, selection blocked, source state contradicted.

### EvaluateDiagnostics
Request: repository ref, optional path, claim refs, artifact refs, evaluation reason, prior diagnostics.
Response: diagnostics, trust changes, handoff eligibility, affected read models, manual checks, warnings to preserve, blocked reasons.
Errors: diagnostic source missing, diagnostic scope ambiguous, cannot classify issue, source review required.

### GenerateHandoff
Request: product path selector, handoff intent, detail level, include refs/diagnostics.
Response: summary ID, handoff type/state, path state, optional next skill, branch-state explanation, trust envelope, evidence/provenance refs, warnings, blocked reasons, boundary, copy allowed, normal next command suppression flag.
Errors: handoff unavailable, blocking diagnostics present, next skill unsupported, boundary explanation required, source support insufficient, out-of-scope request.

### CopyHandoff
Request: summary ID, copy intent, acknowledged warnings, requested format.
Response: copied/suppressed/blocked state, warnings preserved, suppression reason, copied payload shape, diagnostic refs, boundary.
Errors: summary not found, warnings not preserved, copy blocked by diagnostics, next command suppressed, unsupported copy format.

### ListPortfolioPaths
Request: repository ref, optional snapshot, filters, selected path.
Response: path groups, active/parallel/inactive/excluded/unresolved refs, source health, diagnostics, available actions.

### GetSelectedPathDetail
Request: selector plus claims/refs/diagnostics flags.
Response: path fields, trust envelope, claims, evidence/provenance refs, diagnostics, handoff eligibility, available/blocked actions.

### InspectEvidenceRef
Request: claim ref, optional evidence ref, path ID, source hint, preview flag.
Response: claim, evidence link, resolved ref, resolution/read/support state, trust envelope, unsupported claims, diagnostics, preview availability.

### InspectProvenance
Request: optional path, claim ref, artifact ref, include archives/review flags.
Response: records, approval state, confirmed/review-only records, archive refs, canonical targets, source confidence, warnings, diagnostics, handoff relevance.

### GetDiagnostics
Request: optional repository, path, claim refs, levels, severities, include resolved.
Response: issues, summaries by level/severity, affected sources/claims/paths, handoff impacts, manual checks, trust changes.

### ExplainBoundary
Request: selector, optional boundary kind, requested-by, include refs.
Response: path, boundary kind, source status, branch-state explanation, route suppression, suppression reason, promoted boundary flag, evidence/provenance refs, warnings, diagnostics, next-step visibility.

## Evidence And Flow Binding Matrix

All model elements bind to approved flow nodes through the model-tree manifest only. Bindings are not duplicated into the flow tree. See `design/afps-tracker/model-tree-afps-tracker.yaml` for element-level `flow_bindings`.

## Assumptions And Confidence

Confidence is high that ProductPath is the correct selected-path aggregate root because all five framework passes converged on that boundary. Confidence is medium that PortfolioSnapshot should be represented as a thin aggregate root because it is necessary for grouped orientation and unresolved refs but should not own selected-path trust. Confidence is high that parser confidence and source confidence must stay separate.

Remaining risk: the approved flow tree still has `evaluation_priority: pending-key-moments`; this model covers the full approved first read-through and can be narrowed later through normal modify-back if key-moments promotes only a subset.

## Physical Concern Deferrals

Deferred to `$spec-interview`: persistence, caches, storage engines, indexes, migrations, file watchers, parser implementation, API routes, endpoint URLs, transports, auth, authorization, sandbox mechanics, deployment, source preview mechanics, clipboard implementation, and high-fidelity UI layout.

Confirmed Model-Tree Manifest

The following content was written to design/afps-tracker/model-tree-afps-tracker.yaml after compiled YAML approval.

schema_version: v0.1
mode: product-path
topic: afps-tracker
product_path: research/afps-tracker
status: confirmed
flow_tree_ref: design/afps-tracker/flow-tree-afps-tracker.yaml
source_artifacts:
  - docs/history/archive/2026-07-02/002008/design/afps-tracker/_working/state-model-afps-tracker-brief.md
  - docs/history/archive/2026-07-02/002008/docs/history/archive/2026-07-02/002008/design/afps-tracker/state-model-afps-tracker/event-modeling.md
  - docs/history/archive/2026-07-02/002008/docs/history/archive/2026-07-02/002008/design/afps-tracker/state-model-afps-tracker/domain-model.md
  - docs/history/archive/2026-07-02/002008/docs/history/archive/2026-07-02/002008/design/afps-tracker/state-model-afps-tracker/state-machine.md
  - docs/history/archive/2026-07-02/002008/docs/history/archive/2026-07-02/002008/design/afps-tracker/state-model-afps-tracker/data-model.md
  - docs/history/archive/2026-07-02/002008/docs/history/archive/2026-07-02/002008/design/afps-tracker/state-model-afps-tracker/contract-map.md
  - design/afps-tracker/flow-tree-afps-tracker.yaml
  - design/afps-tracker/user-flow-afps-tracker.md
frameworks:
  - event-modeling
  - domain-model
  - state-machine
  - data-model
  - contract-map
entities:
  - id: repository-context
    name: RepositoryContext
    kind: entity
    attributes: [repository_ref, scan_started_at, scan_completed_at, scan_state, source_health, warnings]
    relationships:
      - target: portfolio-snapshot
        cardinality: one-to-zero-or-one
      - target: source-artifact
        cardinality: one-to-many
      - target: diagnostic-issue
        cardinality: one-to-many
    flow_bindings:
      - { flow_node_ref: uf-orient-portfolio, access: triggers }
      - { flow_node_ref: uf-orient-portfolio, access: displays }
      - { flow_node_ref: uf-recover-diagnostics, access: displays }
  - id: portfolio-snapshot
    name: PortfolioSnapshot
    kind: aggregate-root
    attributes: [snapshot_id, repository_ref, progress_manifest_ref, snapshot_state, active_path_refs, excluded_path_refs, parser_confidence, source_confidence]
    lifecycle_ref: portfolio-snapshot-lifecycle
    relationships:
      - target: portfolio-path-ref
        cardinality: one-to-many
      - target: product-path
        cardinality: one-to-many
    flow_bindings:
      - { flow_node_ref: uf-orient-portfolio, access: reads }
      - { flow_node_ref: uf-orient-portfolio, access: displays }
      - { flow_node_ref: uf-explain-boundaries, access: reads }
      - { flow_node_ref: uf-recover-diagnostics, access: transitions }
  - id: portfolio-path-ref
    name: PortfolioPathRef
    kind: entity
    attributes: [path_ref_id, path_id, scope_path, source_status, resolution_state, boundary_kind, diagnostic_refs]
    relationships:
      - target: product-path
        cardinality: many-to-zero-or-one
      - target: diagnostic-issue
        cardinality: one-to-many
    flow_bindings:
      - { flow_node_ref: uf-orient-portfolio, access: displays }
      - { flow_node_ref: uf-explain-boundaries, access: displays }
      - { flow_node_ref: uf-recover-diagnostics, access: writes }
  - id: product-path
    name: ProductPath
    kind: aggregate-root
    attributes: [path_id, label, scope_path, source_status, pipeline_stage, reason, next_skill, revisit_trigger, last_touched, path_state, trust_level, handoff_eligibility, boundary_kind]
    lifecycle_ref: product-path-lifecycle
    relationships:
      - target: source-artifact
        cardinality: one-to-many
      - target: source-backed-claim
        cardinality: one-to-many
      - target: provenance-record
        cardinality: one-to-many
      - target: diagnostic-issue
        cardinality: one-to-many
      - target: handoff-summary
        cardinality: one-to-many
    flow_bindings:
      - { flow_node_ref: uf-orient-portfolio, access: displays }
      - { flow_node_ref: uf-verify-selected-path, access: reads }
      - { flow_node_ref: uf-verify-selected-path, access: writes }
      - { flow_node_ref: uf-handoff-resume, access: reads }
      - { flow_node_ref: uf-explain-boundaries, access: reads }
      - { flow_node_ref: uf-explain-boundaries, access: displays }
  - id: source-artifact
    name: SourceArtifact
    kind: entity
    attributes: [artifact_id, artifact_ref, artifact_kind, source_role, read_status, approval_status, freshness_state, parser_confidence, source_confidence, warnings]
    lifecycle_ref: source-artifact-lifecycle
    relationships:
      - target: source-backed-claim
        cardinality: many-to-many
      - target: provenance-record
        cardinality: many-to-many
      - target: diagnostic-issue
        cardinality: one-to-many
    flow_bindings:
      - { flow_node_ref: uf-verify-selected-path, access: reads }
      - { flow_node_ref: uf-inspect-source-provenance, access: reads }
      - { flow_node_ref: uf-inspect-source-provenance, access: displays }
      - { flow_node_ref: uf-recover-diagnostics, access: transitions }
  - id: source-backed-claim
    name: SourceBackedClaim
    kind: entity
    attributes: [claim_id, path_id, claim_kind, claim_text, support_status, parser_confidence, source_confidence, trust_level, derived_from, warnings]
    relationships:
      - target: evidence-link
        cardinality: one-to-zero-or-many
      - target: diagnostic-issue
        cardinality: one-to-many
    flow_bindings:
      - { flow_node_ref: uf-verify-selected-path, access: displays }
      - { flow_node_ref: uf-inspect-source-provenance, access: reads }
      - { flow_node_ref: uf-inspect-source-provenance, access: displays }
      - { flow_node_ref: uf-recover-diagnostics, access: reads }
      - { flow_node_ref: uf-handoff-resume, access: reads }
  - id: evidence-link
    name: EvidenceLink
    kind: entity
    attributes: [evidence_link_id, claim_id, evidence_ref, resolved_ref, resolution_state, support_status, read_status, source_hint, warnings]
    lifecycle_ref: evidence-link-lifecycle
    relationships:
      - target: source-artifact
        cardinality: many-to-zero-or-one
    flow_bindings:
      - { flow_node_ref: uf-inspect-source-provenance, access: triggers }
      - { flow_node_ref: uf-inspect-source-provenance, access: displays }
      - { flow_node_ref: uf-recover-diagnostics, access: transitions }
  - id: provenance-record
    name: ProvenanceRecord
    kind: entity
    attributes: [provenance_id, path_id, provenance_ref, provenance_kind, approval_state, decision_summary, canonical_target, archive_refs, confidence, warnings]
    lifecycle_ref: provenance-record-lifecycle
    relationships:
      - target: source-artifact
        cardinality: many-to-many
    flow_bindings:
      - { flow_node_ref: uf-inspect-source-provenance, access: reads }
      - { flow_node_ref: uf-inspect-source-provenance, access: displays }
      - { flow_node_ref: uf-recover-diagnostics, access: reads }
      - { flow_node_ref: uf-handoff-resume, access: reads }
  - id: diagnostic-issue
    name: DiagnosticIssue
    kind: entity
    attributes: [issue_id, issue_kind, severity, level, state, affected_refs, affected_claims, affected_paths, handoff_impact, recommended_manual_check]
    lifecycle_ref: diagnostic-issue-lifecycle
    flow_bindings:
      - { flow_node_ref: uf-recover-diagnostics, access: writes }
      - { flow_node_ref: uf-recover-diagnostics, access: displays }
      - { flow_node_ref: uf-recover-diagnostics, access: transitions }
      - { flow_node_ref: uf-orient-portfolio, access: displays }
      - { flow_node_ref: uf-handoff-resume, access: reads }
  - id: handoff-summary
    name: HandoffSummary
    kind: entity
    attributes: [summary_id, path_id, handoff_type, copy_state, confidence, next_skill, branch_state_explanation, handoff_boundary, included_evidence_refs, included_provenance_refs, included_diagnostic_refs, blocked_reasons]
    lifecycle_ref: handoff-summary-lifecycle
    relationships:
      - target: evidence-link
        cardinality: many-to-many
      - target: provenance-record
        cardinality: many-to-many
      - target: diagnostic-issue
        cardinality: many-to-many
    flow_bindings:
      - { flow_node_ref: uf-handoff-resume, access: triggers }
      - { flow_node_ref: uf-handoff-resume, access: writes }
      - { flow_node_ref: uf-handoff-resume, access: displays }
      - { flow_node_ref: uf-explain-boundaries, access: displays }
state_machines:
  - id: portfolio-snapshot-lifecycle
    subject: PortfolioSnapshot
    states:
      - { name: unscanned, maps_to_ui_state: "Empty initial portfolio frame" }
      - { name: scanning, maps_to_ui_state: "Loading portfolio overview" }
      - { name: no-afps-state, maps_to_ui_state: "Empty/no-manifest state" }
      - { name: manifest-malformed, maps_to_ui_state: "Blocking parse diagnostic" }
      - { name: paths-discovered, maps_to_ui_state: "Grouped portfolio rows" }
      - { name: partial, maps_to_ui_state: "Visible warning/partial badges" }
      - { name: source-backed, maps_to_ui_state: "Clean portfolio overview" }
      - { name: blocked, maps_to_ui_state: "Blocking portfolio diagnostic" }
    transitions:
      - { from: unscanned, event: ScanPortfolio, to: scanning }
      - { from: scanning, event: ProgressManifestMissing, to: no-afps-state }
      - { from: scanning, event: ProgressManifestMalformed, to: manifest-malformed }
      - { from: scanning, event: ProductPathRecordDiscovered, to: paths-discovered }
      - { from: paths-discovered, event: DiagnosticIssueRaised, guard: non_blocking_portfolio_issue, to: partial }
      - { from: paths-discovered, event: DiagnosticIssueClassified, guard: no_blocking_issues, to: source-backed }
      - { from: partial, event: DiagnosticIssueClassified, guard: blocking_portfolio_issue, to: blocked }
  - id: product-path-lifecycle
    subject: ProductPath
    states:
      - { name: undiscovered, maps_to_ui_state: "Unresolved active ref or absent row" }
      - { name: discovered, maps_to_ui_state: "Portfolio row" }
      - { name: selected, maps_to_ui_state: "Selected path loading frame" }
      - { name: source-inventorying, maps_to_ui_state: "Source checks loading" }
      - { name: source-backed, maps_to_ui_state: "Clean selected-path detail" }
      - { name: partial, maps_to_ui_state: "Partial detail with unresolved refs" }
      - { name: warning, maps_to_ui_state: "Warning detail and handoff caveats" }
      - { name: blocked, maps_to_ui_state: "Blocked detail and diagnostics" }
      - { name: inactive, maps_to_ui_state: "Inactive path explanation" }
      - { name: promoted-boundary, maps_to_ui_state: "Promoted boundary explanation" }
      - { name: out-of-scope, maps_to_ui_state: "Out-of-scope explanation" }
    transitions:
      - { from: undiscovered, event: ProductPathRecordDiscovered, to: discovered }
      - { from: discovered, event: ProductPathRecordExcluded, to: inactive }
      - { from: discovered, event: PromotedBoundaryDetected, to: promoted-boundary }
      - { from: discovered, event: ProductPathSelected, to: selected }
      - { from: selected, event: ScopedSourceInventoryStarted, to: source-inventorying }
      - { from: source-inventorying, event: ClaimSupportEvaluated, guard: required_claims_supported, to: source-backed }
      - { from: source-inventorying, event: EvidenceRefUnresolved, guard: non_core_support_missing, to: partial }
      - { from: source-backed, event: DiagnosticIssueRaised, guard: non_blocking_caveat, to: warning }
      - { from: warning, event: DiagnosticIssueClassified, guard: blocking_issue, to: blocked }
  - id: source-artifact-lifecycle
    subject: SourceArtifact
    states: [referenced, resolving, found, parsed, confirmed, review-only, amended, archived, missing, unreadable, malformed, stale, unsupported]
    transitions:
      - { from: referenced, event: ScopedSourceInventoryStarted, to: resolving }
      - { from: resolving, event: ScopedResearchArtifactResolved, to: found }
      - { from: resolving, event: ScopedResearchArtifactMissing, to: missing }
      - { from: found, event: ProgressManifestParsed, to: parsed }
      - { from: parsed, event: ProvenanceRecordConfirmed, to: confirmed }
      - { from: parsed, event: ProvenanceRecordReviewOnly, to: review-only }
  - id: evidence-link-lifecycle
    subject: EvidenceLink
    states: [unresolved, resolving, resolved, supports-claim, partially-supports-claim, contradicts-claim, inaccessible]
    transitions:
      - { from: unresolved, event: EvidenceRefResolutionStarted, to: resolving }
      - { from: resolving, event: EvidenceRefResolved, to: resolved }
      - { from: resolved, event: ClaimSupportEvaluated, guard: supports, to: supports-claim }
      - { from: resolved, event: ClaimSupportEvaluated, guard: partial_support, to: partially-supports-claim }
      - { from: resolved, event: ClaimSupportEvaluated, guard: contradiction, to: contradicts-claim }
  - id: provenance-record-lifecycle
    subject: ProvenanceRecord
    states: [missing, discovered, review, confirmed, amended, archived, partial, contradicted]
    transitions:
      - { from: missing, event: ProvenanceRecordDiscovered, to: discovered }
      - { from: discovered, event: ProvenanceRecordConfirmed, to: confirmed }
      - { from: discovered, event: ProvenanceRecordReviewOnly, to: review }
      - { from: confirmed, event: AmendmentDetected, to: amended }
  - id: diagnostic-issue-lifecycle
    subject: DiagnosticIssue
    states: [none, raised, classified, warning, blocked, partial, resolved-by-source-review]
    transitions:
      - { from: none, event: DiagnosticIssueRaised, to: raised }
      - { from: raised, event: DiagnosticIssueClassified, to: classified }
      - { from: classified, event: SeverityPolicyApplied, guard: non_blocking, to: warning }
      - { from: classified, event: SeverityPolicyApplied, guard: blocking, to: blocked }
      - { from: classified, event: SeverityPolicyApplied, guard: incomplete, to: partial }
  - id: handoff-summary-lifecycle
    subject: HandoffSummary
    states: [unavailable, requested, clean-copy, warning-copy, blocked, explanatory, promoted-boundary, out-of-scope, copied, suppressed]
    transitions:
      - { from: unavailable, event: HandoffGenerationRequested, to: requested }
      - { from: requested, event: CleanCopyPrepared, to: clean-copy }
      - { from: requested, event: WarningCopyPrepared, to: warning-copy }
      - { from: requested, event: HandoffBlocked, to: blocked }
      - { from: requested, event: InactivePathExplained, to: explanatory }
      - { from: requested, event: PromotedBoundaryDetected, to: promoted-boundary }
      - { from: requested, event: OutOfScopeRequestExplained, to: out-of-scope }
events:
  - { id: repository-scan-started, name: RepositoryScanStarted, flow_bindings: [{ flow_node_ref: uf-orient-portfolio, access: triggers }] }
  - { id: product-path-selected, name: ProductPathSelected, flow_bindings: [{ flow_node_ref: uf-orient-portfolio, access: triggers }, { flow_node_ref: uf-verify-selected-path, access: writes }] }
  - { id: claim-support-evaluated, name: ClaimSupportEvaluated, flow_bindings: [{ flow_node_ref: uf-inspect-source-provenance, access: reads }, { flow_node_ref: uf-recover-diagnostics, access: reads }] }
  - { id: diagnostic-issue-raised, name: DiagnosticIssueRaised, flow_bindings: [{ flow_node_ref: uf-recover-diagnostics, access: writes }] }
  - { id: handoff-summary-prepared, name: HandoffSummaryPrepared, flow_bindings: [{ flow_node_ref: uf-handoff-resume, access: displays }] }
  - { id: boundary-explanation-requested, name: BoundaryExplanationRequested, flow_bindings: [{ flow_node_ref: uf-explain-boundaries, access: triggers }] }
commands:
  - { id: scan-portfolio, name: ScanPortfolio, flow_bindings: [{ flow_node_ref: uf-orient-portfolio, access: triggers }] }
  - { id: select-product-path, name: SelectProductPath, flow_bindings: [{ flow_node_ref: uf-orient-portfolio, access: triggers }, { flow_node_ref: uf-verify-selected-path, access: writes }] }
  - { id: evaluate-diagnostics, name: EvaluateDiagnostics, flow_bindings: [{ flow_node_ref: uf-recover-diagnostics, access: writes }] }
  - { id: generate-handoff, name: GenerateHandoff, flow_bindings: [{ flow_node_ref: uf-handoff-resume, access: triggers }, { flow_node_ref: uf-explain-boundaries, access: triggers }] }
  - { id: copy-handoff, name: CopyHandoff, flow_bindings: [{ flow_node_ref: uf-handoff-resume, access: writes }] }
read_models:
  - { id: portfolio-overview, name: Portfolio Overview, flow_bindings: [{ flow_node_ref: uf-orient-portfolio, access: displays }] }
  - { id: selected-path-detail, name: Selected Path Detail, flow_bindings: [{ flow_node_ref: uf-verify-selected-path, access: displays }] }
  - { id: evidence-inspector, name: Evidence Inspector, flow_bindings: [{ flow_node_ref: uf-inspect-source-provenance, access: displays }] }
  - { id: provenance-timeline, name: Provenance Timeline, flow_bindings: [{ flow_node_ref: uf-inspect-source-provenance, access: displays }] }
  - { id: diagnostics-panel, name: Diagnostics Panel, flow_bindings: [{ flow_node_ref: uf-recover-diagnostics, access: displays }] }
  - { id: handoff-summary, name: Handoff Summary, flow_bindings: [{ flow_node_ref: uf-handoff-resume, access: displays }, { flow_node_ref: uf-explain-boundaries, access: displays }] }
policies:
  - { id: source-backed-display-rule, name: Source-backed display rule, flow_bindings: [{ flow_node_ref: uf-verify-selected-path, access: reads }, { flow_node_ref: uf-inspect-source-provenance, access: reads }] }
  - { id: unresolved-ref-preservation-rule, name: Unresolved ref preservation rule, flow_bindings: [{ flow_node_ref: uf-orient-portfolio, access: displays }, { flow_node_ref: uf-recover-diagnostics, access: transitions }] }
  - { id: boundary-suppression-rule, name: Boundary suppression rule, flow_bindings: [{ flow_node_ref: uf-explain-boundaries, access: displays }, { flow_node_ref: uf-handoff-resume, access: displays }] }
  - { id: confidence-separation-rule, name: Confidence separation rule, flow_bindings: [{ flow_node_ref: uf-inspect-source-provenance, access: reads }, { flow_node_ref: uf-recover-diagnostics, access: reads }] }
  - { id: warning-preservation-rule, name: Warning preservation rule, flow_bindings: [{ flow_node_ref: uf-handoff-resume, access: displays }] }
contracts:
  - id: scan-portfolio-contract
    name: ScanPortfolio
    kind: command
    request_shape: [repository_context, include_inactive, include_diagnostics, source_refs]
    response_shape: [scan_state, repository_ref, portfolio_snapshot_id, source_health, path_counts, active_path_refs, excluded_path_refs, unresolved_path_refs, diagnostics, read_models_updated]
    error_shape: [no-afps-state, progress-manifest-missing, progress-manifest-malformed, permission-denied, scan-partial, source-unreadable]
    flow_bindings:
      - { flow_node_ref: uf-orient-portfolio, access: triggers }
      - { flow_node_ref: uf-recover-diagnostics, access: transitions }
  - id: selected-path-detail-contract
    name: GetSelectedPathDetail
    kind: query
    request_shape: [selector, include_claims, include_refs, include_diagnostics]
    response_shape: [path_id, label, scope_path, source_status, path_state, pipeline_stage, reason, next_skill, trust, claims, evidence_refs, provenance_refs, diagnostics, handoff_eligibility, available_actions, blocked_actions]
    error_shape: [path-not-selected, path-not-found, source-artifact-missing, path-detail-partial, path-detail-blocked, path-state-contradicted]
    flow_bindings:
      - { flow_node_ref: uf-verify-selected-path, access: reads }
      - { flow_node_ref: uf-verify-selected-path, access: displays }
  - id: inspect-evidence-ref-contract
    name: InspectEvidenceRef
    kind: query
    request_shape: [claim_ref, evidence_ref, path_id, source_hint, preview_requested]
    response_shape: [claim_id, claim_text, evidence_link_id, evidence_ref, resolved_ref, resolution_state, read_status, support_status, source_hint, trust, diagnostics, preview_available]
    error_shape: [claim-not-found, evidence-ref-missing, evidence-ref-unresolved, source-preview-unavailable, evidence-inaccessible, claim-contradicted]
    flow_bindings:
      - { flow_node_ref: uf-inspect-source-provenance, access: displays }
      - { flow_node_ref: uf-recover-diagnostics, access: transitions }
  - id: generate-handoff-contract
    name: GenerateHandoff
    kind: command
    request_shape: [selector, handoff_intent, detail_level, include_refs, include_diagnostics]
    response_shape: [summary_id, handoff_type, handoff_state, path_id, state, pipeline_stage, next_skill, branch_state_explanation, confidence, evidence_refs, provenance_refs, warnings, blocked_reasons, boundary, copy_allowed, normal_next_command_suppressed]
    error_shape: [handoff-unavailable, blocking-diagnostics-present, next-skill-unsupported, boundary-explanation-required, source-support-insufficient, out-of-scope-request]
    flow_bindings:
      - { flow_node_ref: uf-handoff-resume, access: triggers }
      - { flow_node_ref: uf-explain-boundaries, access: displays }

Flow Binding Matrix

Flow nodeReadsWrites or triggersDisplaysTransitions
uf-orient-portfolioRepositoryContext, PortfolioSnapshot, PortfolioPathRef, ProductPath, SourceArtifact, DiagnosticIssueScanPortfolio, SelectProductPath, scan state, selected path targetPortfolio Overview, grouped path rows, source health, active/parallel/inactive/unresolved statesunscanned, scanning, no-AFPS, malformed, paths-discovered, partial, source-backed, blocked
uf-verify-selected-pathProductPath, SourceArtifact, SourceBackedClaim, EvidenceLink, ProvenanceRecord, TrustEnvelopeSelected-path context and source inventorySelected Path Detail with source-backed, inferred, partial, warning, and blocked labelsselected, source-inventorying, source-backed, partial, warning, blocked
uf-inspect-source-provenanceSourceBackedClaim, EvidenceLink, SourceArtifact, ProvenanceRecordEvidence resolution, provenance classification, diagnostic re-evaluation when trust changesEvidence Inspector, Provenance Timeline, resolved/unresolved/support/contradiction statesresolved, supports-claim, partially-supports-claim, contradicted, confirmed, review-only, missing
uf-recover-diagnosticsDiagnosticIssue, affected source/claim/path/portfolio/handoff refsEvaluateDiagnostics, severity, affected level, handoff impact, trust degradationDiagnostics Panel, warning/blocking/partial groups, recommended manual checksraised, classified, warning, blocked, partial, resolved-by-source-review
uf-handoff-resumeProductPath, SourceBackedClaim, EvidenceLink, ProvenanceRecord, DiagnosticIssue, HandoffSummaryGenerateHandoff, CopyHandoff, copy state, included refs, blocked reasonsHandoff Summary, clean/warning/blocked copy state, suppression reasonsrequested, clean-copy, warning-copy, blocked, copied, suppressed
uf-explain-boundariesPortfolioPathRef, ProductPath, BoundaryKind, HandoffSummary, source rationaleExplainBoundary, boundary handoff generation, next-command suppressionInactive, promoted-boundary, out-of-scope, unsupported, unresolved explanationinactive, promoted-boundary, out-of-scope, explanatory, suppressed

Visual Model

Logical ERD

RepositoryContext PortfolioSnapshot ProductPath SourceArtifact SourceBackedClaim ProvenanceRecord EvidenceLink HandoffSummary
RelationshipCardinality
RepositoryContext to PortfolioSnapshotone to zero-or-one
PortfolioSnapshot to ProductPathone to many
ProductPath to SourceBackedClaimone to many
SourceBackedClaim to EvidenceLinkone to zero-or-many
ProductPath to HandoffSummaryone to many over time

Product Path Lifecycle

discovered selected source-inventorying source-backed partial warning blocked inactive clean-copy promoted-boundary out-of-scope
State familyHandoff effect
source-backedEligible for clean copy when diagnostics are non-blocking.
partial or warningEligible only when warnings remain visible and are included.
blockedSuppresses clean handoff and may suppress all next-command output.
inactive/promoted/out-of-scopeProduces explanatory or boundary handoff instead of normal route.

Assumptions And Deferrals

ItemStatusDecision impact
ProductPath is the main aggregate root.High confidenceAll five framework passes converged here.
PortfolioSnapshot is a thin aggregate for orientation.Medium confidenceNeeded for grouped paths and unresolved refs, but should not own selected-path trust.
Parser confidence and source confidence remain separate.High confidencePrevents a confident parser from masking weak source support, or vice versa.
Key-moments is still pending.Known caveatThis model covers the approved first read-through and can be narrowed through modify-back later.
Storage, endpoints, auth, migrations, indexes, deployment, file watchers, parser implementation, and UI layout.DeferredOwned by `$spec-interview` or later implementation work, not this logical model.

Confirmed File Changes

PathConfirmed actionNotes
design/afps-tracker/domain-model-afps-tracker.mdCreated canonical model docMatches confirmed content rendered above.
design/afps-tracker/model-tree-afps-tracker.yamlCreated canonical model-tree manifestMatches confirmed content rendered above with status confirmed.
design/afps-tracker/flow-tree-afps-tracker.yamlUpdated after approvalAttach branches[].model_ref for the modeled branches and optional top-level model_tree_ref. Do not touch route.
research/afps-tracker/glossary.mdAppended approved glossary termsGlossary gate approved additions.
docs/history/archive/YYYY-MM-DD/HHMMSS/...Archived working cursor after canonical writeArchived under docs/history/archive/2026-07-02/002008/.

Approval Record

alignment_status: confirmed

confirmation_date: 2026-07-02

approval_source: final compiled response YAML pasted into $state-model afps-tracker.

This page is current for the completed alignment cycle. Later research may amend it only by archiving this confirmed page and highlighting the amendment.

GateDecisionTarget pathNotes
Domain modelapprovedesign/afps-tracker/domain-model-afps-tracker.mdNo notes.
Model tree manifestapprovedesign/afps-tracker/model-tree-afps-tracker.yamlNo notes.
Flow-tree model attachmentapprovedesign/afps-tracker/flow-tree-afps-tracker.yamlNo notes.
Glossary additionsapproveresearch/afps-tracker/glossary.mdNo notes.
# Invoke with: $state-model afps-tracker
command: "$state-model afps-tracker"
alignment_page: alignment/state-model-afps-tracker.html
response_status: complete
approval_status: ready-for-agent-review
required_gate_status: complete
unanswered_required_questions: []
gate_answers:
  - section: "Domain model"
    gate_type: "approval"
    status: "answered"
    answer: "approve"
    notes: ""
    target_path: "design/afps-tracker/domain-model-afps-tracker.md"
  - section: "Model tree manifest"
    gate_type: "approval"
    status: "answered"
    answer: "approve"
    notes: ""
    target_path: "design/afps-tracker/model-tree-afps-tracker.yaml"
  - section: "Flow-tree model attachment"
    gate_type: "approval"
    status: "answered"
    answer: "approve"
    notes: ""
    target_path: "design/afps-tracker/flow-tree-afps-tracker.yaml"
  - section: "Glossary additions"
    gate_type: "approval"
    status: "answered"
    answer: "approve"
    notes: ""
    target_path: "research/afps-tracker/glossary.md"
agent_routing:
  workflow: design-tree-loop
  parent_skill: state-model
  command: "$state-model afps-tracker"
  topic: afps-tracker
  product_path: research/afps-tracker
  gate_owner: parent-orchestrator
  gate_type: state-model-alignment
  next_resolution: parent-resolves-from-yaml-and-filesystem