@ogygie/core 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ogygie/core",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Ogygie framework core: manifest/spec/error schemas, generic tenancy and gate tooling. Ships TypeScript sources — Ogygie products run tsx/vitest by construction (D1).",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -349,3 +349,27 @@ describe("manifest — bloc vocabulary (spec product-vocabulary-gate B2)", () =>
349
349
  expect(issue?.path.join(".")).toBe("vocabulary.entries.1.canonical");
350
350
  });
351
351
  });
352
+
353
+ describe("manifest — apps vendored (spec product-vocabulary-gate B3, v3)", () => {
354
+ function manifestWithApp(app: Record<string, unknown>) {
355
+ return {
356
+ version: 1,
357
+ product: { name: "acme", description: "SaaS générique servant de fixture aux tests du manifeste." },
358
+ apps: [{ name: "tooling", path: "packages/tooling", type: "front", entryPoint: "packages/tooling/src/main.tsx", ...app }],
359
+ features: [],
360
+ conventions: { agentsMd: "AGENTS.md", failuresMd: "FAILURES.md", specsFolder: "specs/" },
361
+ };
362
+ }
363
+
364
+ it("une app déclarée vendored: true est acceptée", () => {
365
+ expect(OgygieManifestSchema.safeParse(manifestWithApp({ vendored: true })).success).toBe(true);
366
+ });
367
+
368
+ it("une app sans le champ reste la norme (le produit maintient son code)", () => {
369
+ expect(OgygieManifestSchema.safeParse(manifestWithApp({})).success).toBe(true);
370
+ });
371
+
372
+ it("MUTATION : `vendored: false` est refusé — pas de troisième état", () => {
373
+ expect(OgygieManifestSchema.safeParse(manifestWithApp({ vendored: false })).success).toBe(false);
374
+ });
375
+ });
@@ -159,6 +159,19 @@ export const OgygieManifestSchema = z.object({
159
159
  path: z.string(),
160
160
  type: z.enum(["api", "front", "gateway"]),
161
161
  entryPoint: z.string(),
162
+ /**
163
+ * Code the product HOSTS without maintaining it — imported as-is from
164
+ * elsewhere, the framework's own dev tooling being the typical case.
165
+ * A vendored app is skipped by the vocabulary gate: a product's business
166
+ * vocabulary has no claim over code it will never rename.
167
+ *
168
+ * A literal `true`, like `shared` on a table: an app is either vendored
169
+ * (and says so) or the product's own (and stays silent) — no third
170
+ * state. The derogation is declared here, machine-readably, and the gate
171
+ * ANNOUNCES it on every run — one that stops being visible is one that
172
+ * gets forgotten.
173
+ */
174
+ vendored: z.literal(true).optional(),
162
175
  }),
163
176
  ),
164
177
  features: z.array(FeatureManifestSchema),