Skip to content

feat(assemble): add product stages assembled from the exported objects - #64

Merged
nichinichisou0609 merged 1 commit into
redesign/depotfrom
redesign/products
Oct 14, 2026
Merged

nichinichisou0609 merged 1 commit into
redesign/depotfrom
redesign/products

Conversation

@nichinichisou0609

Copy link
Copy Markdown
Collaborator

Summary

Product stages (nnnotes.pipeline.assemble.ProductStage) assemble a product from the unity.export results of the objects it reaches, never from a bundle.

Request roots

  • A product's task starts from root objects: the objects of the catalog keys it gives for the subject (through the address table of link.addresses), and the object ids it names.
  • assemble.request(stages, products, env) turns that into the fact roots ({keys, objects}), which the unit request uses. A run then exports the units those roots reach and nothing else of their bundles.

Reach and the object table

  • reach walks the units of the roots, then every unit an item of a reached unit references, through the results.
  • A sprite whose atlas is in another bundle takes its image from the sprite.crop result of that atlas.
  • A reached unit that the request did not export is an error of the request; an object no census holds is listed as missing.
  • The reached objects become the object table (nnnotes.objects/1), the task's only input: class, name, item status, files by role, the object holding a contained one, and the reason code of a generic, unsupported or failed one. Its key therefore follows exactly the files the product can read.

Result and layout

  • The result holds the product's files as <task id>#<path>, its object table as <task id>#objects, and one item for the subject (exported, or unsupported with a reason code).
  • layout.product_entries / layout.product_manifest place a product for a player: every file and every file of its objects at assets/<sha256>.<ext>, and one manifest (nnnotes.product/1) per product listing its files and its objects' files. A file several products share is written once.
  • view.voices now reads the address table through the same cached reader as the unit table.

Docs

  • New docs/products.md, with the request, the object table, the layout and the manifest; stages.md, contracts.md and schemas.md updated, plus objects.schema.json and product.schema.json.

Test plan

  • Full test suite
  • New tests/pipeline/test_assemble.py over the bundle fixtures of test_objexport: the request, the table of a prefab hierarchy, a cross-bundle atlas crop, waiting, the result, pruning and the layout
  • ruff, pyright, import-linter, mkdocs build --strict

Not in this PR

The CLI wiring and the first real product (Live2D) come with the assemblers; no command reads a product yet.

🤖 Generated with Claude Code

A product stage (nnnotes.pipeline.assemble.ProductStage) makes one task
per subject from root objects: the objects of the catalog keys it gives
for the subject, through the address table, and the object ids it names.
Its task reaches the units holding its roots and every unit an item of a
reached unit references, through the unity.export results; a sprite whose
atlas is in another bundle takes its image from sprite.crop.

- The task's input is the object table of what it reaches
  (nnnotes.objects/1): each object's class, name, item status and files,
  the object holding a contained one, and the referenced objects no census
  holds. Its key therefore follows exactly the files it can read.
- The result holds the product's own files as `<task id>#<path>`, its
  object table as `<task id>#objects` and one item for the subject.
- The unit request takes the fact `roots` ({keys, objects}):
  `assemble.request` gives it from the products asked for, so a run
  exports the units their roots reach and nothing else of their bundles.
- layout.product_entries and layout.product_manifest place products for
  a player: every file at `assets/<sha256>.<ext>` and a manifest
  (nnnotes.product/1) per product listing its files and its objects'
  files.
- view.voices reads the address table through the same cached reader.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nichinichisou0609
nichinichisou0609 merged commit 1518bc0 into redesign/depot Oct 14, 2026
8 checks passed
@nichinichisou0609
nichinichisou0609 deleted the redesign/products branch October 14, 2026 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant