asset walker (WIP)

This commit is contained in:
bQUARKz 2026-03-18 19:39:13 +00:00
parent 92c74c7bd0
commit 6a9e09bd88
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
5 changed files with 440 additions and 1 deletions

View File

@ -0,0 +1,200 @@
# PR-24 Asset File Cache Hydration and Walker Reuse
Domain Owner: `docs/packer`
Cross-Domain Impact: `docs/studio`
## Briefing
The runtime loader already walks asset roots and produces `walkResult`, and `PackerWorkspacePaths` already reserves `assets/.prometeu/cache.json`.
What is still missing is the actual cache lifecycle:
- previous cache is not loaded before a walk;
- walkers do not receive prior file facts for comparison;
- `walkResult` does not become a durable cache artifact after the scan.
That leaves the current runtime path unable to reuse prior file knowledge such as `lastModified`, `size`, `fingerprint`, and family-specific probe metadata.
This PR introduces the first durable asset file cache flow for the runtime-backed packer wave.
It also tightens how walk output becomes part of the runtime snapshot and how diagnostics are split between normal aggregated surfaces and file-scoped UI-facing surfaces.
## Objective
Deliver an asset-scoped file cache stored in `assets/.prometeu/cache.json`, hydrated before the runtime walk and refreshed from the current `walkResult` after the walk completes, while also attaching the current `walkResult` to the runtime snapshot.
## Dependencies
- [`./PR-14-project-runtime-core-snapshot-model-and-lifecycle.md`](./PR-14-project-runtime-core-snapshot-model-and-lifecycle.md)
- [`./PR-15-snapshot-backed-asset-query-services.md`](./PR-15-snapshot-backed-asset-query-services.md)
- [`./PR-16-write-lane-command-completion-and-used-write-services.md`](./PR-16-write-lane-command-completion-and-used-write-services.md)
- [`./PR-21-point-in-memory-snapshot-updates-after-write-commit.md`](./PR-21-point-in-memory-snapshot-updates-after-write-commit.md)
- [`../specs/2. Workspace, Registry, and Asset Identity Specification.md`](../specs/2.%20Workspace,%20Registry,%20and%20Asset%20Identity%20Specification.md)
- [`../specs/4. Build Artifacts and Deterministic Packing Specification.md`](../specs/4.%20Build%20Artifacts%20and%20Deterministic%20Packing%20Specification.md)
- [`../specs/5. Diagnostics, Operations, and Studio Integration Specification.md`](../specs/5.%20Diagnostics,%20Operations,%20and%20Studio%20Integration%20Specification.md)
## Scope
- define the durable schema for `assets/.prometeu/cache.json`
- store cache entries per asset and per discovered file, not as one flat global fingerprint bag
- restrict cache and internal file walk analysis to assets that are already registered and therefore have stable `asset_id`
- load prior cache state during runtime snapshot bootstrap and refresh
- pass prior asset-scoped cache entries into the asset walker
- let walkers compare current file observations against prior cached facts such as `lastModified`, `size`, `fingerprint`, and family-specific metadata
- treat the current `walkResult` as the source used to build the next durable cache state
- attach the current `walkResult` to the in-memory runtime snapshot for later query and UI use
- persist refreshed cache after a successful runtime load or write-path point patch that recomputes asset content
- keep cache miss, corruption, or version mismatch non-fatal for normal asset reads
- keep the Studio-visible asset query surface stable while the cache becomes an internal optimization and comparison input
- keep diagnostics out of the durable cache artifact
- sink general walk diagnostics into the normal asset/runtime diagnostics surface
- preserve file-scoped diagnostics as segregated walk output for UI consumers
## Non-Goals
- no remote/shared cache
- no final `build`/`pack` incremental pipeline
- no background watch service or external reconcile loop
- no silent reuse of stale cache entries when file identity no longer matches the current asset file
- no cache file per asset root; the baseline artifact remains the workspace-level `assets/.prometeu/cache.json`
- no UI contract that exposes raw cache internals directly to Studio
- no cache support for unregistered assets; registration remains the prerequisite for internal file analysis and durable cache ownership
## Execution Shape
`PR-24` should be treated as an umbrella execution plan, not as one direct implementation PR.
This work should be split into smaller follow-up PRs so cache persistence, walker reuse policy, and runtime snapshot integration can each land with narrow tests and isolated regressions.
## Execution Method
1. Introduce a packer-owned cache repository around `PackerWorkspacePaths.cachePath(project)`.
The repository must load, validate, and save one workspace cache artifact without leaking raw filesystem JSON handling into loaders or walkers.
2. Define a versioned durable cache model.
The baseline model should include:
- workspace-level schema/version fields
- asset-scoped entries keyed by stable `asset_id`
- file-scoped entries keyed by normalized relative path inside the asset root
- reusable file facts such as mime type, size, `lastModified`, content fingerprint, and family-specific probe metadata
- no persisted diagnostics; diagnostics remain runtime results produced by the current walk only
3. Extend walker inputs so previous cache is available during content probing.
The walker contract should receive the prior asset cache view together with the declaration and asset root, rather than forcing each concrete walker to reopen cache storage on its own.
Unregistered assets do not enter this flow; they must be registered first before internal file analysis and cache ownership apply.
4. Define cache comparison rules inside the walker layer.
Baseline rules:
- if current file `size` differs from cached `size`, cached data is invalid immediately
- if current file `lastModified` is after cached `lastModified`, cached data is invalid immediately
- content hash or fingerprint should be the last comparison step, used only when the cheaper checks do not already force invalidation and the policy still needs stronger confirmation
- if prior file facts remain valid under that ordered comparison policy, the walker may reuse prior metadata instead of recomputing everything
- if identity facts differ, the walker must treat the file as changed and emit fresh probe output
- missing prior cache is a normal cache miss, not an error
- corrupted or incompatible prior cache should surface diagnostics or operational logging as appropriate, then fall back to a cold walk
5. Promote `walkResult` from transient scan output to cache refresh input.
After a successful walk, the loader must convert only the cacheable portions of the current `walkResult` into the next durable asset cache entry set and merge it into the workspace cache model.
Persisted cache data must be limited to reusable probe facts and metadata, never diagnostics.
6. Attach walk output to the runtime snapshot.
The runtime snapshot should retain a dedicated runtime projection of the current walk output, not the raw probe objects themselves, so query services and Studio-facing adapters can access file-scoped probe metadata and file-scoped diagnostics without forcing a new filesystem walk.
The initial runtime posture should keep the full available file set and the subset that is currently build-eligible, plus bank-size measurement data needed by future fixed-size hardware bank checks.
The raw probe may still carry file bytes during the active walk, but the snapshot projection must strip byte payloads before retention.
The snapshot should keep inventory, probe metadata, build-candidate classification, and bank-size measurements, but not whole file contents or raw `PackerFileProbe` instances by default.
Later cleanup may reduce that retained surface, but the first implementation should prefer preserving available walk data rather than prematurely trimming it.
7. Split diagnostic sinks intentionally.
Baseline rule:
- asset-level or walk-level diagnostics that represent the normal operational truth of the asset should flow into the usual runtime/query diagnostics sink
- file-scoped diagnostics produced by probe processing should remain segregated per file inside the walk result projection
- Studio may consume those file-scoped diagnostics for detailed UI rendering, but that segregation must not be lost by collapsing everything into one flat diagnostics list
- none of those diagnostics are persisted in `cache.json`
8. Persist cache only at stable visibility points.
The normal runtime path should save refreshed cache after the loader finishes building a coherent snapshot.
Write-path flows that patch one asset in memory should update only the affected asset cache entry after durable commit and successful re-walk.
9. Keep runtime snapshot and cache ownership aligned.
Runtime snapshot data may retain the current walk output needed by query services, but the durable cache artifact remains a packer-owned operational store under `assets/.prometeu/cache.json`.
10. Emit observability only at meaningful boundaries.
The implementation may emit `cache_hit` and `cache_miss` events or counters, but adapters must not collapse cache behavior into fake asset-change semantics.
## Acceptance Criteria
- runtime load attempts to read `assets/.prometeu/cache.json` before walking assets
- prior asset-scoped cache entries are passed into walkers as comparison input
- cache entries are keyed by stable `asset_id`, not by asset path
- unregistered assets do not receive cache entries and do not undergo internal file analysis before registration
- walkers compare current files against prior facts using ordered checks where `size` invalidates first, `lastModified` invalidates next when the current value is newer, and fingerprint/hash remains the final expensive check
- the current walk output is attached to the in-memory runtime snapshot through a byte-free runtime projection, not through raw probe objects
- the runtime snapshot keeps enough walk data to expose available files, build-candidate files, and bank-size measurement data
- the runtime snapshot does not retain raw bytes for every discovered file by default
- normal asset/runtime diagnostics include the general walk diagnostics that should participate in the standard diagnostics surface
- file-scoped diagnostics remain segregated in the walk result projection for UI consumers
- the resulting `walkResult` is used to refresh the durable cache state
- successful runtime load writes a coherent updated cache artifact back to `assets/.prometeu/cache.json`
- missing, corrupted, or version-mismatched cache does not block snapshot load; the packer falls back to a cold walk
- point write flows that already patch one asset in memory can refresh only that asset's cache slice after commit instead of forcing full cache rebuild
- cache entries are isolated by asset and file path so one asset cannot accidentally reuse another asset's file facts
- persisted cache does not contain diagnostics from prior runs
- Studio list/details behavior remains stable and does not depend on direct cache awareness
## Tests
- loader tests for cold load when `cache.json` is absent
- loader tests for warm load when prior cache exists and matches current files
- loader tests for fallback when `cache.json` is malformed, unreadable, or schema-incompatible
- cache model tests proving asset cache lookup is aligned by `asset_id`
- walker tests proving changed `size` invalidates reuse immediately
- walker tests proving newer `lastModified` invalidates reuse immediately
- walker tests proving fingerprint/hash is evaluated only as the last comparison step when cheaper checks do not already invalidate reuse
- walker tests proving stable files can reuse prior metadata without changing query-visible results
- cache serialization tests proving diagnostics are never written to `cache.json`
- snapshot/query tests proving `walkResult` is attached to the runtime asset model
- tests proving general walk diagnostics sink into the normal diagnostics surface
- tests proving file-scoped diagnostics remain segregated per file for UI-facing consumers
- runtime registry tests for point cache refresh after write commit on one asset
- event or observability tests for `cache_hit` and `cache_miss` boundaries if those signals are emitted in this wave
## Risks and Recovery
- path-keyed cache would become unsafe during relocate flows, so the cache owner key must remain `asset_id`
- overly aggressive cache reuse can hide real content changes if comparison rules are under-specified
- saving cache at the wrong lifecycle point can publish partial truth that no coherent snapshot ever observed
- if one part of the cache flow proves unstable, recovery should disable cache hydration or persistence for that path and preserve the current cold-walk behavior until the narrower follow-up PR is corrected
## Affected Artifacts
- `docs/packer/pull-requests/**`
- `docs/packer/specs/2. Workspace, Registry, and Asset Identity Specification.md`
- `docs/packer/specs/5. Diagnostics, Operations, and Studio Integration Specification.md`
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/PackerWorkspacePaths.java`
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/**`
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/models/**`
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/**`
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/**`
## Suggested Next Step
Derive smaller implementation PRs from `PR-24`:
1. cache model and repository
Scope:
- durable `cache.json` schema
- load/save repository
- `asset_id`-aligned cache lookup
- serialization tests proving diagnostics are excluded
2. walker contract and comparison policy
Scope:
- previous-cache input contract
- ordered invalidation checks by `size`, then newer `lastModified`, then fingerprint/hash
- file-scoped diagnostics preservation
3. runtime snapshot and loader integration
Scope:
- attach `walkResult` to runtime snapshot
- sink general diagnostics into the normal asset/runtime diagnostics surface
- refresh cache from the cacheable parts of `walkResult`
- point write-path refresh for one affected asset

View File

@ -0,0 +1,76 @@
# PR-25 Asset Cache Model and Repository
Domain Owner: `docs/packer`
## Briefing
`PR-24` defines the need for a durable asset file cache in `assets/.prometeu/cache.json`, but the first executable slice should stop at cache persistence itself.
Before walkers or runtime snapshot integration can reuse prior file facts safely, the packer needs a stable cache schema, explicit load/save ownership, and tests that prove the cache is keyed correctly and excludes non-cacheable data.
## Objective
Deliver the durable `cache.json` model and repository, keyed by stable `asset_id`, with no persisted diagnostics.
## Dependencies
- [`./PR-24-asset-file-cache-hydration-and-walker-reuse.md`](./PR-24-asset-file-cache-hydration-and-walker-reuse.md)
- [`./PR-14-project-runtime-core-snapshot-model-and-lifecycle.md`](./PR-14-project-runtime-core-snapshot-model-and-lifecycle.md)
- [`../specs/2. Workspace, Registry, and Asset Identity Specification.md`](../specs/2.%20Workspace,%20Registry,%20and%20Asset%20Identity%20Specification.md)
## Scope
- define the durable schema for `assets/.prometeu/cache.json`
- key asset cache ownership by stable `asset_id`
- omit unregistered assets from durable cache ownership entirely
- key file cache entries by normalized relative path inside the asset root
- persist reusable probe facts only:
- `mimeType`
- `size`
- `lastModified`
- fingerprint/hash
- family-specific metadata
- exclude diagnostics from the durable cache artifact
- add a packer-owned repository for cache load/save and schema validation
## Non-Goals
- no walker contract changes yet
- no cache comparison or reuse policy yet
- no runtime snapshot model changes yet
- no Studio adapter changes
## Execution Method
1. Add cache model types under the packer runtime model layer.
2. Define one versioned workspace cache artifact for `assets/.prometeu/cache.json`.
3. Encode asset entries by `asset_id`, never by asset root path.
4. Encode file entries by normalized asset-relative path.
5. Add repository load/save behavior with safe fallback on missing or invalid cache files.
6. Prove by tests that diagnostics cannot be serialized into the durable cache artifact.
## Acceptance Criteria
- the packer has explicit model types for the durable cache artifact
- cache ownership is keyed by `asset_id`
- unregistered assets do not receive durable cache entries
- file cache entries are keyed by normalized relative file path
- repository load on absent cache returns a safe empty state
- malformed or schema-incompatible cache can be rejected cleanly without crashing the runtime load path
- diagnostics are not part of the serialized cache schema
## Validation
- schema serialization tests for workspace cache
- repository round-trip tests for valid cache content
- repository tests for absent cache file
- repository tests for malformed cache file
- cache model tests proving `asset_id`-aligned lookup
- serialization tests proving diagnostics are excluded from `cache.json`
## Affected Artifacts
- `docs/packer/pull-requests/**`
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/**`
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/models/**`
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/**`

View File

@ -0,0 +1,71 @@
# PR-26 Walker Cache Input and Comparison Policy
Domain Owner: `docs/packer`
## Briefing
Once the durable cache model exists, the next narrow step is to let walkers consume prior cached file facts without coupling them to cache storage.
This PR defines the cache-aware walker contract and the ordered invalidation policy that decides when prior metadata can be reused and when a fresh probe is mandatory.
## Objective
Deliver walker-side prior-cache input and a deterministic comparison policy ordered by `size`, then newer `lastModified`, then fingerprint/hash.
## Dependencies
- [`./PR-24-asset-file-cache-hydration-and-walker-reuse.md`](./PR-24-asset-file-cache-hydration-and-walker-reuse.md)
- [`./PR-25-asset-cache-model-and-repository.md`](./PR-25-asset-cache-model-and-repository.md)
## Scope
- extend walker inputs so they receive prior asset cache state
- keep walkers independent from cache repository I/O
- apply walker-side internal file analysis only to already-registered assets
- define ordered invalidation checks:
- changed `size` invalidates immediately
- newer `lastModified` invalidates immediately
- fingerprint/hash is evaluated last when stronger confirmation is still needed
- allow walkers to reuse prior metadata when cached facts remain valid
- preserve file-scoped diagnostics in walk output
## Non-Goals
- no runtime snapshot attachment yet
- no cache persistence integration in the loader yet
- no point write-path refresh yet
- no Studio UI contract changes
## Execution Method
1. Update walker contracts to accept prior asset cache input together with asset root and declaration.
2. Keep cache lookup outside concrete walkers; they should receive an already-resolved asset cache view.
3. Implement the ordered invalidation policy in the shared walker path.
4. Reuse prior metadata only when the ordered checks keep the cached entry valid.
5. Preserve file-scoped diagnostics in the resulting walk output for later runtime and UI consumption.
## Acceptance Criteria
- walkers receive prior asset cache entries as input
- the walker layer does not perform cache repository I/O directly
- unregistered assets are excluded from internal file analysis and cache-aware walker reuse
- changed `size` invalidates prior reuse immediately
- newer `lastModified` invalidates prior reuse immediately
- fingerprint/hash remains the final expensive comparison step
- stable files may reuse prior metadata without changing query-visible semantics
- file-scoped diagnostics remain segregated in walk output
## Validation
- walker tests proving changed `size` invalidates reuse
- walker tests proving newer `lastModified` invalidates reuse
- walker tests proving fingerprint/hash is only evaluated after cheaper checks do not already invalidate reuse
- walker tests proving stable files can reuse prior metadata
- tests proving file-scoped diagnostics remain attached to per-file walk output
## Affected Artifacts
- `docs/packer/pull-requests/**`
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/**`
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/models/**`
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/**`

View File

@ -0,0 +1,88 @@
# PR-27 Runtime WalkResult and Cache Integration
Domain Owner: `docs/packer`
Cross-Domain Impact: `docs/studio`
## Briefing
With cache persistence and walker reuse policy isolated, the final slice is to connect them to the runtime model.
This PR makes the runtime loader hydrate prior cache before the walk, attach the current `walkResult` to the in-memory snapshot, sink general diagnostics into the normal diagnostics surface, preserve file-scoped diagnostics for UI consumers, and refresh the durable cache from the cacheable portions of the current walk.
## Objective
Deliver runtime-side integration of prior cache hydration, `walkResult` snapshot attachment, diagnostics sink split, and refreshed cache persistence.
## Dependencies
- [`./PR-24-asset-file-cache-hydration-and-walker-reuse.md`](./PR-24-asset-file-cache-hydration-and-walker-reuse.md)
- [`./PR-25-asset-cache-model-and-repository.md`](./PR-25-asset-cache-model-and-repository.md)
- [`./PR-26-walker-cache-input-and-comparison-policy.md`](./PR-26-walker-cache-input-and-comparison-policy.md)
- [`./PR-15-snapshot-backed-asset-query-services.md`](./PR-15-snapshot-backed-asset-query-services.md)
- [`./PR-21-point-in-memory-snapshot-updates-after-write-commit.md`](./PR-21-point-in-memory-snapshot-updates-after-write-commit.md)
- [`../specs/5. Diagnostics, Operations, and Studio Integration Specification.md`](../specs/5.%20Diagnostics,%20Operations,%20and%20Studio%20Integration%20Specification.md)
## Scope
- load prior `cache.json` during runtime snapshot bootstrap and refresh
- resolve prior cache by `asset_id` before invoking the walker
- attach a byte-free runtime projection of the current `walkResult` to the in-memory runtime asset model
- retain enough walk data in the runtime snapshot to inspect available files, build-candidate files, and bank-size measurement data
- avoid retaining raw file bytes for the full discovered file set in the runtime snapshot
- sink general walk diagnostics into the normal asset/runtime diagnostics surface
- preserve file-scoped diagnostics as segregated walk output for UI consumers
- refresh and persist cache from the cacheable portions of the current walk
- support point cache refresh for one affected asset after successful write commit and re-walk
## Non-Goals
- no new Studio feature surface beyond exposing already-owned file-scoped walk data
- no background reconcile observer
- no build/incremental pipeline work
## Execution Method
1. Load prior workspace cache at runtime bootstrap and on refresh.
2. Resolve the current asset cache slice by `asset_id` and pass it into the walker.
Assets without `asset_id` are outside this flow and should not receive internal file analysis or cache ownership.
3. Attach a dedicated runtime projection of the current `walkResult` to the runtime snapshot model.
The first implementation should keep the available file set, the build-candidate subset, and bank-size measurement data accessible from the snapshot instead of optimizing that shape away early.
The runtime projection should drop raw file bytes and should not retain raw `PackerFileProbe` objects unless a narrower later use case proves they are needed.
4. Route general walk diagnostics into the standard asset/runtime diagnostics sink.
5. Preserve file-scoped diagnostics inside the walk result projection used by later query/UI consumers.
6. Persist refreshed cache after coherent runtime load completes.
7. Reuse the same logic to refresh one asset cache slice after successful point write commit and re-walk.
## Acceptance Criteria
- runtime load reads prior cache before invoking walkers
- cache lookup passed to the walker is aligned by `asset_id`
- assets without `asset_id` are excluded from cache ownership and internal file analysis
- runtime assets retain a byte-free projection of the current walk output in memory
- runtime assets retain enough walk data to inspect available files, build-candidate files, and bank-size measurement data
- runtime snapshot retention excludes raw file bytes for the general discovered file set
- general walk diagnostics appear in the normal diagnostics surface
- file-scoped diagnostics remain segregated for detailed consumers
- refreshed cache written after runtime load contains only cacheable probe facts and metadata
- point write flows can refresh only one affected asset cache entry after commit
- missing, malformed, or incompatible cache falls back to cold walk without blocking runtime queries
## Validation
- loader tests for cold load without cache
- loader tests for warm load with cache hydration
- snapshot/query tests proving `walkResult` is attached to runtime assets
- diagnostics tests proving general sink aggregation and file-scoped segregation
- cache refresh tests proving the durable artifact is rebuilt from cacheable walk data only
- runtime registry tests for one-asset cache refresh after point write commit
## Affected Artifacts
- `docs/packer/pull-requests/**`
- `docs/packer/specs/5. Diagnostics, Operations, and Studio Integration Specification.md`
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/repositories/**`
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/models/**`
- `prometeu-packer/prometeu-packer-v1/src/main/java/p/packer/services/**`
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/repositories/**`
- `prometeu-packer/prometeu-packer-v1/src/test/java/p/packer/services/**`
- `prometeu-studio/**` query adapter coverage when file-scoped diagnostics become consumable

View File

@ -83,6 +83,10 @@ The current production track for the standalone `prometeu-packer` project is:
21. [`PR-21-point-in-memory-snapshot-updates-after-write-commit.md`](./PR-21-point-in-memory-snapshot-updates-after-write-commit.md)
22. [`PR-22-delete-asset-action-confirmation-and-fs-first-manifest-removal.md`](./PR-22-delete-asset-action-confirmation-and-fs-first-manifest-removal.md)
23. [`PR-23-move-asset-action-wizard-and-fs-first-relocation.md`](./PR-23-move-asset-action-wizard-and-fs-first-relocation.md)
24. [`PR-24-asset-file-cache-hydration-and-walker-reuse.md`](./PR-24-asset-file-cache-hydration-and-walker-reuse.md)
25. [`PR-25-asset-cache-model-and-repository.md`](./PR-25-asset-cache-model-and-repository.md)
26. [`PR-26-walker-cache-input-and-comparison-policy.md`](./PR-26-walker-cache-input-and-comparison-policy.md)
27. [`PR-27-runtime-walkresult-and-cache-integration.md`](./PR-27-runtime-walkresult-and-cache-integration.md)
Current wave discipline from `PR-11` onward:
@ -93,4 +97,4 @@ Current wave discipline from `PR-11` onward:
Recommended dependency chain:
`PR-01 -> PR-02 -> PR-03 -> PR-04 -> PR-05 -> PR-06 -> PR-07 -> PR-08 -> PR-09 -> PR-10 -> PR-11 -> PR-12 -> PR-13 -> PR-14 -> PR-15 -> PR-16 -> PR-17 -> PR-18 -> PR-19 -> PR-20 -> PR-21 -> PR-22 -> PR-23`
`PR-01 -> PR-02 -> PR-03 -> PR-04 -> PR-05 -> PR-06 -> PR-07 -> PR-08 -> PR-09 -> PR-10 -> PR-11 -> PR-12 -> PR-13 -> PR-14 -> PR-15 -> PR-16 -> PR-17 -> PR-18 -> PR-19 -> PR-20 -> PR-21 -> PR-22 -> PR-23 -> PR-24 -> PR-25 -> PR-26 -> PR-27`