# THIS YOU — DEV Factory API Runtime Flow v1

**Status:** implementation specification  
**Scope:** DEV / CMS integration with THIS YOU Production Factory API  
**Applies to:** current V2 admin + MagazineInstance / ChapterGeneration architecture  
**Primary goal:** replace manual Factory → ZIP → `/teleport/` handoff with direct API-driven production while preserving Teleport as the canonical import layer and manual fallback.

---

# 1. Core runtime principle

Normal production must become:

```text
MagazineInstance
↓
Generate with API
↓
Factory job
↓
Factory complete
↓
DEV downloads result package/artifacts
↓
shared import service
↓
ChapterGeneration
↓
READY
```

The operator should not manually:

```text
download ZIP
copy ZIP into /teleport/
open Teleport
press GO
```

for the normal API path.

The `/teleport/` folder remains available for:

```text
manual Custom GPT handoff
legacy package import
debugging
recovery
offline/manual production
```

---

# 2. Two required production flows

Launch implementation must support exactly two primary flows.

## FLOW A — Full Chapter Production

Use when:

```text
chapter is new
products may change
personalized copy may change
HERO may change
full Factory pipeline is required
```

Factory owns:

```text
Scene DNA interpretation
Look Thesis
product research
product verification
product image acquisition
Visual Locks
personalization
HERO generation
fidelity QA
bounded correction/retry
final production package
```

DEV owns:

```text
canonical input
identity linkage
job submission
job persistence
polling
artifact download
import
chapter versioning
MagazineInstance UX
activation/publishing
```

## FLOW B — HERO Reroll

Use when:

```text
current chapter setup is good
products should stay unchanged
copy should stay unchanged
scene should stay unchanged
operator only wants a fresh HERO candidate
```

Factory creates:

```text
new HERO candidate
new Fidelity result
reroll diagnostics
```

DEV must:

```text
preserve current HERO
store reroll as candidate
show current vs new
allow explicit operator choice
```

A reroll must never silently replace the current HERO.

---

# 3. Teleport architecture decision

## 3.1 One import domain, multiple entry paths

Do not maintain separate parsing/business logic for:

```text
manual Teleport
Factory API full package
Factory API reroll
```

Create/refactor a shared import domain service.

Conceptual internal interface:

```text
TeleportImportService
```

Suggested responsibilities:

```text
validate routing identity
validate package/artifact schemas
validate file/hash integrity where available
normalize API / manual package differences
import products
import Visual Locks
import personalization
import fidelity
import HERO
preserve provenance
create ChapterGeneration
```

Entry paths:

```text
Manual /teleport/ package
        ↓
TeleportImportService.importFullPackage()

Factory API package
        ↓
TeleportImportService.importFullPackage()

Factory HERO reroll
        ↓
HeroCandidateService.importRerollCandidate()
```

The reroll path may reuse low-level artifact/provenance helpers from Teleport, but it is **not** a full chapter re-import.

## 3.2 Important reroll rule

Accepting a reroll must NOT:

```text
rerun full Teleport
re-import products
re-import chapter copy
re-import Visual Locks
regenerate anything
```

Acceptance only promotes the already-downloaded candidate HERO/version.

---

# 4. Factory connection configuration

Factory must be configuration-driven.

Development example:

```php
'production_factory' => [
    'enabled' => true,
    'api_url' => 'http://127.0.0.1:8787',
    'api_token' => '<secret>',
    'connect_timeout_seconds' => 5,
    'request_timeout_seconds' => 30,
    'poll_interval_seconds' => 5,
],
```

Development connection:

```text
Windows / Laragon
↓
SSH tunnel
↓
127.0.0.1:8787
↓
Factory 127.0.0.1:8000
```

DEV must never use Factory server filesystem paths such as:

```text
/opt/this-you/...
```

All result transfer must happen through API/artifact endpoints.

Secrets must remain outside source control.

---

# 5. Factory API client

Create one DEV-side API client abstraction.

Suggested:

```text
ProductionFactoryClient
```

Responsibilities:

```text
health()
ready()

importIdentityPackage()

createChapterJob()
getChapterJob()
getChapterJobResult()

createHeroReroll()
getHeroReroll()
getHeroRerollResult()

downloadArtifact()
```

Optional later:

```text
createHeroCorrection()
getHeroCorrection()
getHeroCorrectionResult()
```

The rest of CMS code must not build raw Factory URLs manually.

---

# 6. Authentication and idempotency

Every protected Factory call must use:

```http
Authorization: Bearer <token>
```

Every POST generation call must use:

```http
Idempotency-Key: <unique-key>
```

## Full production idempotency

Recommended key source:

```text
magazine_instance_id
chapter_number
input_sha256
generation_intent
```

Example conceptual key:

```text
full-mi184-ch03-<short-input-hash>
```

Repeated click with identical intent/request must reuse the existing job where Factory allows it.

A deliberate new full regeneration must generate a new explicit run/version intent.

## Reroll idempotency

Reroll must use a unique key per requested fresh alternative.

Example:

```text
reroll-<source_job_id>-<local-request-uuid>
```

Rapid double-click must not create two unintended rerolls.

---

# 7. Required local persistence

Do not rely on browser/session memory.

Add persistent local records for Factory work.

Recommended logical model:

```text
factory_jobs
```

Fields conceptually:

```text
id
magazine_instance_id
chapter_id
chapter_number

job_type
    full_production
    hero_reroll
    hero_correction

factory_job_id
source_factory_job_id

status
    queued
    running
    complete
    failed

idempotency_key

production_state
error_code
error_message

estimated_cost_usd
elapsed_seconds

request_snapshot_json
result_snapshot_json
artifact_map_json
diagnostics_json

chapter_generation_id
candidate_id

created_at
updated_at
completed_at
```

A separate table is optional if equivalent durable fields already exist in `chapter_generations` / job tables.

The important requirement is:

> A browser refresh or DEV restart must not lose the Factory job relationship.

---

# 8. Chapter-level UX states

Internal Factory has many stages.

Normal admin must not expose all of them.

For a chapter, operator-facing states should remain simple:

```text
NO RESULT
GENERATING
READY
FAILED
REROLL GENERATING
REROLL READY TO COMPARE
```

Internally store exact Factory stage/status for debug.

Normal UI should not show:

```text
look_thesis
product_freeze
visual_lock
fidelity_qa
targeted_fix
```

as operator workflow steps.

Those belong in Edit / Debug.

---

# 9. FLOW A — Full Chapter Production runtime

## A1. Operator action

On MagazineInstance chapter card:

```text
GENERATE WITH API
```

Available when:

```text
Factory integration enabled
required reader/identity data exists
chapter has canonical production input
no identical full job is already actively running
```

If an existing good chapter exists, the button may instead be:

```text
REGENERATE FULL CHAPTER
```

A full regeneration creates a new ChapterGeneration version and must not destructively erase the current good version before the replacement succeeds.

---

# 10. FLOW A — build request

DEV builds the canonical chapter input using the existing contract.

Required source data includes:

```text
identity_package_id
issue
reader
reader_references contract where applicable
style mode
chapter
Scene DNA
selection rules
output/result contract
```

DEV does not add its own styling intelligence.

Request:

```http
POST /v1/chapter-production/jobs
```

Body:

```json
{
  "identity_package_id": "user_0004__intake_001",
  "chapter_production_input": {
    "...": "full canonical input"
  },
  "mode": "production",
  "overrides": {
    "quality": null,
    "pose_target": null,
    "expression_target": null,
    "run_id": null
  }
}
```

Store locally before/at submission:

```text
request snapshot
input hash if available
Idempotency-Key
MagazineInstance
chapter
local job row
```

---

# 11. FLOW A — submit response

Expected Factory response:

```json
{
  "job_id": "prod_...",
  "status": "queued",
  "idempotent_reuse": false
}
```

Persist:

```text
factory_job_id
status
idempotent_reuse if useful
```

Chapter UI immediately becomes:

```text
GENERATING
```

The initial admin request must return quickly.

Do not hold one PHP request open for the full generation time.

---

# 12. FLOW A — polling

Poll:

```http
GET /v1/chapter-production/jobs/{job_id}
```

Recommended interval:

```text
5–10 seconds
```

Polling must be asynchronous from the long Factory task.

Acceptable implementation:

```text
AJAX/fetch polling while page is open
+
server-side persisted job state
```

Later background polling may be added.

Stop polling when:

```text
complete
failed
```

A browser refresh should reload the stored `factory_job_id` and resume polling.

---

# 13. FLOW A — failure handling

If Factory returns:

```text
failed
```

store:

```text
error_code
error_message
job_id
last status/result payload
```

UI:

```text
FAILED
[OPEN DIAGNOSTIC]
[TRY AGAIN]
```

Critical rule:

> A failed new production job must never overwrite the last known-good chapter generation.

If the chapter had no previous result, it remains without a result.

If it had a previous good result, that version stays active.

---

# 14. FLOW A — final result

On complete call:

```http
GET /v1/chapter-production/jobs/{job_id}/result
```

Read/store:

```text
production_state
automation_qa_passed
qa_mode
human_review_required
operator_activation_required
estimated_cost_usd
elapsed_seconds
artifacts
```

Factory completion must not activate/publish the whole MagazineInstance.

CMS still owns:

```text
ACTIVATE MAGAZINE
```

---

# 15. FLOW A — artifact download

Normal full-production integration should download the Factory `package` artifact and preserve it.

Recommended source:

```text
artifacts.package
```

Also optionally fetch:

```text
hero
manifest
fidelity
```

for quick UI/validation if useful.

Every artifact request uses Bearer auth.

Downloaded package should be stored in a private/local production area before import.

Example logical location:

```text
factory_imports/<factory_job_id>/production-result.zip
```

Do not place it manually in public `/teleport/`.

---

# 16. FLOW A — automatic import through Teleport service

After successful package download:

```text
Factory package
↓
TeleportImportService.importFullPackage()
```

The importer must validate at least:

```text
issue_slug
reader_id
chapter_number
manifest/package consistency
final HERO exists
supported schemas
```

Where hashes exist, validate them.

Import should preserve:

```text
factory_job_id
manifest
Factory provenance
package archive
cost/elapsed metadata
fidelity evidence
```

---

# 17. FLOW A — ChapterGeneration behavior

A successful full Factory import creates a new:

```text
ChapterGeneration
```

Examples:

```text
v1
v2
v3
```

Recommended source:

```text
openai_factory_api
```

The generation contains:

```text
products
personalized copy
Visual Locks
fidelity
HERO
package provenance
factory_job_id
```

## New chapter

If there was no previous generation:

```text
new generation becomes current/active chapter draft
```

## Full regeneration of an existing chapter

Recommended behavior:

```text
old generation remains in history
new completed generation becomes current chapter draft
```

Magazine-level publication/activation still remains under operator control.

If the MagazineInstance had previously been activated and chapter content changes, mark the magazine as requiring re-activation according to existing V2 revision logic.

---

# 18. FLOW A — completion UI

After automatic import succeeds:

```text
READY
```

Show:

```text
HERO thumbnail
View in magazine
Generate new HERO
Regenerate full chapter
Edit / Debug
```

Optional secondary info:

```text
cost
elapsed time
generation version
```

Do not require an extra:

```text
IMPORT RESULT
```

button in the normal flow.

Factory complete + valid automatic import should finish the operation.

---

# 19. FLOW B — HERO reroll availability

`Generate new HERO` appears only when the active/current chapter generation has a valid:

```text
source factory_job_id
```

and the source production job is complete.

Do not require:

```text
re-upload products
re-run product search
rebuild chapter input
manual ZIP
```

Reroll is based on Factory's completed source job context.

---

# 20. FLOW B — create reroll

Operator clicks:

```text
GENERATE NEW HERO
```

DEV calls:

```http
POST /v1/chapter-production/jobs/{source_job_id}/hero-rerolls
```

Body:

```json
{}
```

Store:

```text
reroll_job_id
source_factory_job_id
idempotency_key
chapter_generation_id
```

The current HERO remains unchanged.

UI:

```text
REROLL GENERATING
```

---

# 21. FLOW B — poll reroll

Poll:

```http
GET /v1/hero-rerolls/{reroll_job_id}
```

Stop on:

```text
complete
failed
```

Failure rule:

> Reroll failure must not modify any active chapter content.

On failure:

```text
current HERO stays active
candidate job remains in history/debug
```

---

# 22. FLOW B — fetch result

On complete:

```http
GET /v1/hero-rerolls/{reroll_job_id}/result
```

Read/store:

```text
recommended
fresh_generation
diagnostics
estimated_cost_usd
elapsed_seconds
hero artifact
fidelity artifact
reroll_result artifact
```

The Factory may recommend the candidate, but the operator decides.

---

# 23. FLOW B — candidate import

Download:

```text
new HERO
new Fidelity
reroll result JSON
```

Store them as a non-active candidate.

Recommended logical object:

```text
HeroCandidate
```

or equivalent existing generation/history representation.

Required provenance:

```text
source_factory_job_id
reroll_job_id
source_chapter_generation_id
hero_path
fidelity
diagnostics
recommended
cost
created_at
decision
```

Decision values:

```text
pending
accepted
rejected
```

Do not overwrite the active HERO here.

---

# 24. FLOW B — compare UI

When candidate is ready, show:

```text
CURRENT HERO        NEW HERO
[image]             [image]
```

Below show useful Factory diagnostics:

```text
Recommended: yes/no

Face fidelity:
before
after
delta

Flattering:
before
after

Age:
before
after

Overall status after

Cost
```

Primary actions:

```text
KEEP CURRENT
USE NEW HERO
```

Do not require the operator to understand Factory internals.

---

# 25. FLOW B — Keep current

When operator clicks:

```text
KEEP CURRENT
```

Then:

```text
active HERO remains unchanged
candidate.decision = rejected
candidate/revision may remain in history
```

No full chapter data changes.

Another reroll may later be requested with a new idempotency key.

---

# 26. FLOW B — Use new HERO

When operator clicks:

```text
USE NEW HERO
```

Then:

```text
new candidate HERO becomes active chapter HERO
old HERO remains in history
candidate.decision = accepted
accepted_at stored
accepted_by stored if available
```

Preserve:

```text
products
copy
layout
Visual Locks
source full-production job
```

Only HERO-related active revision changes.

Acceptance must NOT:

```text
rerun Factory
rerun Teleport full import
rerun product generation
replace products
replace copy
```

If MagazineInstance was already activated, changing HERO should mark it as needing re-activation under existing revision semantics.

---

# 27. Relationship between full generation and reroll

Example:

```text
Full production:
factory_job_id = prod_001
ChapterGeneration v1
HERO A
```

Reroll:

```text
source_job_id = prod_001
reroll_job_id = reroll_001
HERO B
```

If rejected:

```text
v1 still uses HERO A
```

If accepted:

```text
chapter active visual revision uses HERO B
products/copy remain from prod_001
```

A later full chapter regeneration:

```text
factory_job_id = prod_002
ChapterGeneration v2
new products/copy/HERO may all change
```

Rerolls for `prod_001` and `prod_002` must remain distinguishable.

---

# 28. Optional HERO correction flow

Factory exposes:

```http
POST /v1/chapter-production/jobs/{source_job_id}/hero-corrections
```

Launch UI does not need to expose this.

When implemented, correction follows the same candidate rule as reroll:

```text
Factory correction
↓
candidate HERO
↓
compare
↓
operator accepts/rejects
```

Never auto-apply.

Suggested future UI:

```text
Look more like me
Look like me but better
```

but keep hidden until reroll flow is stable.

---

# 29. Automatic vs manual Teleport

## Normal API production

```text
Factory API
↓
download package
↓
TeleportImportService
↓
chapter
```

No manual folder.

## Manual Custom GPT / recovery

```text
production-result.zip
↓
/teleport/
↓
GO — TELEPORT
↓
same TeleportImportService
```

This guarantees both paths converge on the same import semantics.

---

# 30. Required provenance

For every full Factory generation preserve:

```text
factory_job_id
input/request snapshot
result snapshot
manifest
package ZIP
estimated_cost_usd
elapsed_seconds
created/completed timestamps
ChapterGeneration ID
```

For every reroll preserve:

```text
reroll_job_id
source_factory_job_id
source ChapterGeneration
diagnostics
recommended
estimated_cost_usd
elapsed_seconds
candidate HERO
candidate Fidelity
accepted/rejected decision
```

Do not throw away failed-job provenance required for debugging.

---

# 31. Factory connection failure UX

If tunnel/API is unavailable:

```text
Factory unavailable
```

Normal PHP/admin page must continue functioning.

Do not crash MagazineInstance screen.

Suggested action:

```text
RETRY CONNECTION
```

Existing chapters remain viewable/editable.

Manual Teleport remains available as fallback.

---

# 32. Polling safety

Polling one job must never affect another.

Required:

```text
each chapter stores its own Factory job
each reroll stores its own reroll job
status requests are keyed by exact job ID
```

Architecture must allow:

```text
CH01 generating
CH02 generating
CH03 ready
CH04 reroll generating
```

at the same time.

DEV must not assume sequential chapter execution.

---

# 33. Last-known-good rule

This is a non-negotiable invariant:

> Never destroy or replace the last known-good result until a new result is complete, valid, imported successfully, and—where required—explicitly accepted.

Applies to:

```text
full regeneration
reroll
future correction
artifact download failure
Factory failure
Teleport/import failure
browser refresh
DEV restart
```

---

# 34. Full production package remains canonical audit artifact

Even though DEV can download HERO/manifest/fidelity separately, preserve the full Factory ZIP when available.

Purpose:

```text
debugging
re-import
audit
future migration
Factory regression analysis
```

The API integration should not discard it after import.

---

# 35. Suggested internal PHP components

Names are implementation suggestions, not external contracts.

```text
lib/factory-client.php
    ProductionFactoryClient

lib/factory-jobs.php
    local Factory job persistence/helpers

lib/teleport-import-service.php
    canonical full-package importer

lib/hero-candidates.php
    reroll/correction candidate storage + activation
```

Admin actions/pages may include:

```text
admin/factory-generate.php
admin/factory-job-status.php
admin/factory-reroll.php
admin/factory-reroll-status.php
admin/hero-compare.php
```

Exact filenames may follow the existing codebase style.

Do not duplicate importer logic inside controllers.

---

# 36. MagazineInstance screen — desired final UX

Example:

```text
JĀNIS KAUSS
AUTUMN 2026

CH01
[hero]
READY
View in magazine
Generate new HERO
Regenerate full chapter

CH02
GENERATING…

CH03
[hero]
READY
View in magazine
Generate new HERO
Regenerate full chapter

CH04
Generate with API
```

If reroll candidate exists:

```text
CH03
NEW HERO READY TO COMPARE

[COMPARE]
```

No manual API endpoint knowledge should be required from the operator.

---

# 37. Full API flow sequence

```text
Operator clicks Generate with API
↓
DEV builds canonical input
↓
DEV resolves identity_package_id
↓
POST Factory full-production job
↓
store factory_job_id
↓
return admin UI immediately
↓
poll status asynchronously
↓
Factory COMPLETE
↓
GET result
↓
download package artifact
↓
TeleportImportService validates/imports
↓
ChapterGeneration created
↓
chapter becomes READY
↓
operator sees result in magazine
```

---

# 38. HERO reroll sequence

```text
Operator clicks Generate new HERO
↓
DEV gets source factory_job_id
↓
POST reroll
↓
store reroll_job_id
↓
poll
↓
Factory COMPLETE
↓
GET reroll result
↓
download candidate HERO + fidelity
↓
store candidate, inactive
↓
show Current vs New
↓
operator:
    Keep current
    OR
    Use new HERO
```

---

# 39. Acceptance criteria — Factory connection

- [ ] Factory URL configurable.
- [ ] Bearer token stored outside source control.
- [ ] `/health` can be checked.
- [ ] Tunnel/API failure does not crash admin.
- [ ] No Factory server filesystem path is used directly.
- [ ] Artifact endpoints are the only source of remote artifacts.

---

# 40. Acceptance criteria — Full chapter production

- [ ] `Generate with API` exists in MagazineInstance chapter UI.
- [ ] Canonical chapter input is sent unchanged except required API envelope.
- [ ] Correct identity package is linked.
- [ ] Bearer auth sent.
- [ ] Idempotency-Key sent.
- [ ] `factory_job_id` persisted.
- [ ] Browser refresh does not lose running job.
- [ ] Polling is asynchronous.
- [ ] Failed job preserves existing good chapter.
- [ ] Complete job result is fetched.
- [ ] Full package is downloaded automatically.
- [ ] Package is imported through shared Teleport import service.
- [ ] Manual `/teleport/` copy is not required.
- [ ] Correct reader/issue/chapter receives result.
- [ ] Products are imported.
- [ ] Personalized copy is imported.
- [ ] Visual Lock data is imported.
- [ ] Fidelity/provenance is imported.
- [ ] HERO is imported.
- [ ] New ChapterGeneration is created.
- [ ] Factory job ID remains linked.
- [ ] Package archive is preserved.
- [ ] Chapter becomes READY.
- [ ] Magazine is not auto-activated/published.

---

# 41. Acceptance criteria — HERO reroll

- [ ] `Generate new HERO` appears only for valid completed Factory source jobs.
- [ ] Reroll uses source job context.
- [ ] No product search is rerun by DEV.
- [ ] `reroll_job_id` persisted.
- [ ] Reroll polls asynchronously.
- [ ] Failure does not modify current HERO.
- [ ] New HERO and Fidelity artifacts download automatically.
- [ ] Candidate is stored inactive.
- [ ] Current and new HERO are shown for comparison.
- [ ] `recommended` is visible.
- [ ] Face fidelity before/after/delta is available where returned.
- [ ] Flattering before/after shown where returned.
- [ ] Age before/after shown where returned.
- [ ] Cost shown.
- [ ] `Keep current` preserves current HERO.
- [ ] `Use new HERO` explicitly promotes candidate.
- [ ] Old HERO remains in history.
- [ ] Products/copy/layout remain unchanged.
- [ ] Accepting candidate does not rerun full Teleport import.
- [ ] Accepted reroll provenance is preserved.

---

# 42. Acceptance criteria — safety / resilience

Test deliberately:

```text
wrong token
Factory unavailable
missing Idempotency-Key
duplicate submit
unknown job
running source job
failed source job
artifact download failure
corrupted package
invalid image
invalid JSON
browser refresh while running
DEV restart while running
multiple chapters running
multiple rapid reroll clicks
reroll failure after good HERO exists
```

Expected invariant:

> Last known-good chapter/HERO remains safe.

---

# 43. Launch scope

Implement now:

```text
Factory configuration
Factory client
persistent local Factory jobs
full chapter submit/poll/result
automatic full-package download
shared Teleport service import
Generate with API UI
HERO reroll submit/poll/result
candidate storage
compare UI
Keep current / Use new HERO
```

Keep for later:

```text
HERO correction UI
batch generation
subscription automation
background worker sophistication
push/webhook callbacks
automatic print submission
```

---

# 44. Definition of done

The integration is complete when this works:

## Full chapter

```text
Open MagazineInstance
↓
Generate with API
↓
wait
↓
chapter appears READY with products + copy + HERO
```

with no manual `/teleport/` interaction.

## HERO-only

```text
Open ready chapter
↓
Generate new HERO
↓
wait
↓
compare old vs new
↓
choose one
```

without changing the selected products or personalized chapter copy.

---

# Final rule

The system should have **one production import truth**, not one per execution method.

```text
Custom GPT manual package ──┐
                            ├─> shared import domain ─> ChapterGeneration
Factory API full package ───┘

Factory HERO reroll
    └─> candidate import ─> explicit operator accept/reject
```

Normal operator experience:

```text
GENERATE WITH API
↓
READY
```

and, when desired:

```text
GENERATE NEW HERO
↓
COMPARE
↓
KEEP CURRENT / USE NEW HERO
```
