17 KiB
Design: Bundle Hygiene (formerly "Dictionary Marketplace")
Author: zimin.an
Date: 2026-05-12
Status: PROPOSED v2 (post /office-hours + cross-model challenge)
Supersedes: v1 «Dictionary Marketplace» (Approach B: full registry + browse UI + dry-run preview + install dialog, 10-14d)
Scope: ДЗЗ domain, single-tenant (Approach C-revised — bundle format spec + publisher CLI, NO consumer UI)
Sprint estimate: 2-3 days CC, hard cap. Anything beyond requires new design doc.
Blockers: none
TL;DR
v1 предлагал full marketplace (Nexus registry + browse UI + install dialog + dry-run preview + multi-tenancy + dep resolution) за 10-14 days. После /office-hours premise challenge + cross-model challenge — v1 был over-scoped для N=1 customer (ЦУОД anchor only сегодня).
Revised: Formalize bundle format spec + publisher CLI. No consumer-side UI. This is bundle hygiene, не marketplace.
Why bundle hygiene matters at N=1:
- Java team handoff требует documented manifest spec в любом случае — без этого new engineers не знают как добавить новый dict без полного code review pipeline
- Sales artifact — demo prospects «ЦУОД bundle is independently signed/versioned, here's how you'd ship your own» без shipping консьюмерского UI
- Optionality — когда customer #2 signs, bundle format уже defined, можно ship UI quickly (consumer UI = 5-7d incremental)
What this design explicitly is NOT:
- ❌ Browse catalog UI
- ❌ Install dialog в admin-ui
- ❌ Dry-run preview UI
- ❌ Public marketplace
- ❌ Bundle dep resolution / topological install
- ❌ Multi-tenant Nexus namespacing
Anti-feature: если scope expands beyond 2-3 days hard cap → STOP, re-design doc. Don't let founder weekend-prototyping pull this into Approach B by accident.
Premises (validated через /office-hours 2026-05-12, including cross-model challenge)
P1. Marketplace UI/registry value scales с N customers. At N=1 → near-zero. Build only когда customer #2 LOI/contract стадия с extensibility language.
P2. Bundle format + signing + manifest valuable AT N=1 — separable concern от marketplace UI. Doubles as Java handoff spec + sales demo.
P3. ЦУОД go-live (anchor v1) уже live на v2.14.0 prod. Дальнейший development must support handoff readiness, не speculative future features.
P4. No customer #2 named with deadline as of 2026-05-12. Sales conversations ongoing (Альтум integration в process, гидрометео preliminary discussions). Marketplace UI build now = infrastructure ahead of validated need.
P5. «Defer entirely» (Approach A) was directionally right но oversold. Cross-model challenge revealed: pure defer assumes founder won't drift to greenfield work. Pre-committed scoped C contains damage better than aspirational pure-defer.
P6. Bundle hygiene work ROI положителен независимо от marketplace decision: даже если marketplace UI shipped'нется только в Q4 2026 или никогда — formal bundle spec нужен для Java handoff (target 2-3 months).
P7. Hard cap 2-3 days CC. No scope creep. If пилот results in «we should add UI now», that's NEW design doc, new /office-hours, fresh decision.
What ships в v2 (bundle hygiene, 2-3 days)
1. Bundle manifest format spec
ordinis-cuod-bundle/manifest.yaml (NEW file, replaces ad-hoc Maven module structure):
apiVersion: ordinis.io/v1
kind: Bundle
metadata:
id: ru.cuod.dzz-ground-segment
name: ЦУОД ДЗЗ — наземный сегмент
version: 1.0.0 # semver, follows Maven artifact version
description: |
40 dictionaries для управления наземным сегментом ДЗЗ:
КА, типы КА, наземные станции, антенны, частотные диапазоны.
domain: dzz
scope: PUBLIC
author: ЦУОД team
license: proprietary
signature: ed25519:base64... # added by publisher CLI
dictionaries:
# Existing list from ordinis-cuod-bundle/src/main/resources/bundles/cuod/
- name: spacecraft
schemaVersion: 1.0.0
scope: PUBLIC
schemaRef: dictionaries/spacecraft/schema.json # relative path
sampleDataRef: dictionaries/spacecraft/sample.json # optional
- name: satellite_type
schemaVersion: 1.0.0
scope: PUBLIC
schemaRef: dictionaries/satellite_type/schema.json
# ... 38 more
Migration: Existing ad-hoc ordinis-cuod-bundle/src/main/resources/bundles/cuod/ structure refactored to match manifest. No behavior change — bundle still loaded via existing Maven module pattern. Just adds spec on top.
2. Publisher CLI (ordinis-bundle-publisher Maven plugin)
mvn ordinis:bundle-publish \
-Dbundle.path=ordinis-cuod-bundle \
-Dnexus.url=https://nexus.corp/ordinis-bundles/private/cuod \
-Dsigning.key=$BUNDLE_SIGNING_KEY
Steps плагина:
- Read
manifest.yaml - Validate каждый
schemaRefis valid JSON Schema 7 via existingSchemaValidator - Compute bundle archive (tar.gz of manifest + schemas + sample data)
- Sign archive с ed25519 key
- Upload to corp Nexus с canonical path
<bundle-id>/<version>/bundle.tar.gz - Generate
bundle.sigadjacent
Reuses: existing Maven publish patterns в repo, corp Nexus credentials через GitLab CI variables.
3. Signature verification helper
BundleSignatureVerifier.java в new module ordinis-bundle-spec (lightweight):
public class BundleSignatureVerifier {
public boolean verify(byte[] archive, byte[] signature, PublicKey publicKey);
}
Не consumed в v2 (no consumer side). Built as documentation artifact для future marketplace work — defines verification contract.
4. Documentation
docs/user-guide/bundle-authoring.md:
- Bundle structure spec (manifest.yaml format)
- How to publish (mvn command + Nexus setup)
- Versioning semantics (semver, breaking change rules)
- Schema authoring conventions reused from existing JavaDoc patterns
docs/integration/bundle-format-spec.md:
- Formal spec для Java team handoff
- Manifest schema definition
- Signing contract
- Future consumer protocol (placeholder)
What does NOT ship в v2 (explicit non-goals)
| Feature | Why not |
|---|---|
| ❌ Admin UI «browse bundles» | No customer #2 with browse use case |
| ❌ Install dialog в admin-ui | Customer-specific deployment = helm + values, не runtime install |
| ❌ Dry-run preview UI | No install operation to preview |
| ❌ Multi-tenant Nexus namespacing | N=1 customer, single namespace OK |
| ❌ Dep resolution / topological install | Single bundle, no inter-bundle deps yet |
| ❌ Public catalog | Customer #2+ + community curation = v3 |
| ❌ Bundle uninstall flow | No install in admin UI → no uninstall |
| ❌ Bundle update / migration scripts | Manual helm upgrade pattern remains |
Anti-feature commitment: If during 2-3d implementation эти items появляются «just a bit more», STOP. Write new design doc, fresh /office-hours, fresh approval.
Architecture
ordinis-cuod-bundle/ ordinis-bundle-spec/ (NEW module)
├── manifest.yaml ← NEW ├── BundleManifest.java
├── pom.xml ├── BundleSignatureVerifier.java
└── src/main/resources/ └── pom.xml
└── bundles/cuod/
├── dictionaries/ ordinis-bundle-publisher/ (NEW Maven plugin)
│ ├── spacecraft/ ├── BundlePublishMojo.java
│ │ ├── schema.json ├── ManifestValidator.java
│ │ └── sample.json └── pom.xml
│ └── ... (39 more)
└── (existing Maven structure)
│
│ mvn ordinis:bundle-publish
▼
Corp Nexus
ordinis-bundles/private/cuod/
└── ru.cuod.dzz-ground-segment/
└── 1.0.0/
├── bundle.tar.gz
└── bundle.sig
No new pods. No runtime changes к ordinis-app / ordinis-admin-ui. Only build-time tooling + Nexus artifacts.
Approaches Considered
Approach A — Defer entirely (0 days now)
- Pros: Zero sunk cost. Capacity goes to AI metric work / prod hardening / customer #2 acquisition.
- Cons: Java handoff still needs bundle format spec eventually — built later under deadline pressure. Pure defer ~20% adherence (cross-model challenge): founder likely drifts to greenfield marketplace prototyping anyway.
Approach B — Full marketplace v1 (10-14 days, v1 doc original)
- Pros: Real differentiator if customer #2 ships. Demo wow factor.
- Cons: Infrastructure ahead of validated need. Spec drift между hypothetical и real customer #2 requirements. 10-14d sunk cost if N never grows. Triggers Brooks's «is this solving real problem или one we created?»
Approach C-revised — Bundle hygiene (2-3 days, CHOSEN)
- Pros:
- Java handoff readiness (must-have anyway, due in 2-3 months)
- Sales demo asset («signed versioned bundle artifact, here's our hygiene story»)
- Contains founder's marketplace energy в legitimate scope-bounded work
- 5× cheaper than B, не «do nothing» of A
- Future-leverage: when customer #2 needs UI, format already defined → UI 5-7d вместо 10-14d
- Cons:
- «Half feature» if framed as marketplace — мы НЕ frame'им так
- Not consumer-visible (no UI screenshot for demo deck)
- 2-3 days still > 0 days (Approach A); risk founder drifts beyond cap
Recommended Approach: C-revised — Bundle Hygiene
Rationale per /office-hours cross-model synthesis:
-
Java handoff debt avoidance: Manifest spec mandatory anyway when team scales beyond zimin.an. Build now while context fresh, cheaper than retro-spec under deadline.
-
Sales conversation enablement: Prospects asking «can we extend this с our own dictionaries?» get pointed at published bundle artifact + manifest spec — concrete answer без «we'll build it for you».
-
Founder behavior containment: Cross-model challenge правильно отметил: pure defer has ~20% follow-through odds. Pre-committed 2-3d scope легитимизирует bundle work, prevents weekend prototyping что expanded beyond bounds.
-
Optionality preserved для customer #2: If LOI signs Q3-Q4 — UI work spawn separate design doc, builds on this manifest, ships 5-7 days (smaller scope than ahead-of-time 10-14d).
-
Engineering preference «explicit over clever»: Manifest format defined upfront prevents implicit conventions, helpful for Java team handoff.
Implementation plan
| Step | Effort (CC) | Notes |
|---|---|---|
1. New module ordinis-bundle-spec (manifest POJO + verifier) |
3h | Pure Java, no Spring dep |
2. New module ordinis-bundle-publisher (Maven plugin) |
4h | Standard Maven plugin scaffolding |
3. manifest.yaml for ordinis-cuod-bundle (1.0.0 release) |
1h | Generated from existing bundle structure |
| 4. Migrate ad-hoc bundle structure → match manifest paths | 2h | File moves, no logic change |
| 5. Publisher CLI: tar.gz + ed25519 sign + Nexus upload | 4h | BouncyCastle for ed25519 |
| 6. Manifest schema validation в publisher | 2h | Reuses existing SchemaValidator |
| 7. GitLab CI integration (publish job on bundle tag) | 2h | New .gitlab-ci.yml job |
| 8. Tests (publisher Mojo + verifier + manifest parse) | 4h | unit tests, no integration tests needed |
9. docs/user-guide/bundle-authoring.md + docs/integration/bundle-format-spec.md |
3h | Java handoff artifact |
| Total | ~25h (2-3 days CC) | Hard cap. No scope creep. |
Anti-creep checkpoint: After step 9, STOP. Don't add «just one consumer endpoint». Don't add «just a tiny browse list». Those are new design doc territory.
Test plan
| # | Test | Type |
|---|---|---|
| 1 | Manifest parser: valid YAML → typed object | unit |
| 2 | Manifest validation: missing required field → error | unit |
| 3 | Publisher Mojo: happy path → archive + signature generated | unit (Mojo) |
| 4 | Publisher Mojo: invalid schemaRef → fail fast | unit |
| 5 | Signature verifier: signed archive → returns true | unit |
| 6 | Signature verifier: tampered archive → returns false | unit |
| 7 | Signature verifier: wrong public key → returns false | unit |
| 8 | Schema validation reuse: invalid JSON Schema в dict → publisher fails | unit |
No integration / E2E tests — no runtime behavior changes.
Open questions
- Where do signing keys live? GitLab CI variables protected? Vault? Corp HSM? → Defer to ops decision при implement.
- Nexus namespace structure?
ordinis-bundles/private/<customer>/<bundle-id>/<version>/— fine для v1. Multi-tenant adjustments в v2. - Migration breaking? Existing
ordinis-cuod-bundledeployment relies on Maven module loaded at app startup. Manifest spec adds metadata, doesn't change loading. Verify: ordinis-app still loads bundle when manifest.yaml present но new spec module not on classpath (graceful degradation для existing v2.14.0 prod).
Distribution plan
Publisher Maven plugin distributed как corp internal artifact в Nexus. Authors add к their bundle's pom.xml:
<build>
<plugins>
<plugin>
<groupId>cloud.nstart.terravault.ordinis</groupId>
<artifactId>ordinis-bundle-publisher</artifactId>
<version>1.0.0</version>
</plugin>
</plugins>
</build>
Then mvn ordinis:bundle-publish triggered by GitLab CI on tag push (e.g. cuod-bundle-1.0.0).
Bundle.tar.gz uploaded к Nexus. No deployment changes к prod ordinis cluster — bundle archive consumed только by external authors / sales demos.
Success criteria
Quantitative:
- Publisher Mojo completes < 60 sec на ЦУОД bundle (~40 dicts)
- Signature verification < 10ms
- Manifest validation catches 100% malformed manifests in unit tests
Qualitative:
- Java team handoff doc references
bundle-format-spec.mdas authoritative spec - Sales conversations с prospects use «signed versioned bundle» as differentiator
- After 1 month: zero «founder drifted into consumer UI work» violations (scope cap held)
Failure criteria (rollback):
- Publisher Mojo bugs surface в > 2 releases of ordinis-cuod-bundle → reconsider as build-time vs separate plugin
- No sales conversation uses bundle artifact within 3 months → format спека correct, distribution wrong (rare; spec stays anyway)
What I noticed about how you think (during /office-hours)
-
Initial position «build full marketplace» (v1 doc) → accepted «defer entirely» recommendation от me → accepted «bundle hygiene» revision после cross-model challenge. Two reversals in one session = openness to push-back. Это редко — большинство founders defend original scope harder.
-
«давай как рекомендуешь» = trust calibrated на анализ + cross-model agreement. You didn't dismiss subagent challenge OR over-weight it — accepted synthesis as honest reading.
-
Cross-model challenge value: subagent found 4 things I missed (sales artifact, Java handoff, founder psychology drift risk, «treading water» mis-framing). Без cross-model call recommendation бы вышел overly conservative. Session demonstrates value of /office-hours Phase 3.5 even когда первый instinct = skip it.
-
Anti-scope-creep pre-commitment —
Hard cap 2-3 days. No scope creep.line — это founder-level discipline, не engineering preference. Most founders write «target effort 2-3 days» что effectively unconstrained.
Reviewer Concerns
(Spec review skipped в этой session due to context length. Recommend /plan-eng-review separately когда implement starts, especially on:)
- Module dependency graph (
ordinis-bundle-specstandalone OK? circular dep risk если consumed by ordinis-app later?) - Nexus auth credentials lifecycle (GitLab CI vs Vault tradeoff)
- Compatibility: existing prod v2.14.0 deployment should keep working без bundle-spec module
See also
- v1 SUPERSEDED (был «Dictionary Marketplace», full UI + registry + 10-14d). Reasoning for v1 → v2 revision lives в section «Approaches Considered».
- Companion:
ai-schema-assist.md— separate /office-hours design, AI assist authorship. Sequencing: AI assist baseline measurement (P5 prereq) before this. This work doesn't compete для bandwidth — separable. - Office-hours formal doc:
~/.gstack/projects/claude/zimin-main-design-bundle-hygiene-20260512.md(cross-skill discoverable)