mikser-io-layouts 2.11.1 → 2.11.2

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/lib/mcp.js CHANGED
@@ -566,13 +566,36 @@ export function registerCheckTool({ runtime, findEntity, findEntities, useDataba
566
566
  // declared key no layout reads.
567
567
  const knows = (k) => req.has(k) || opt.has(k)
568
568
  || [...req, ...opt].some(d => d.startsWith(`${k}.`) || d.startsWith(`${k}[`))
569
- const isRead = (k) => consumed.has(k)
570
- || [...consumed].some(c => c.startsWith(`${k}.`) || c.startsWith(`${k}[`))
569
+
570
+ // `declaredButNotRead` asks whether a declared key is read by
571
+ // ANY layout, so it is answered against the UNSCOPED contract —
572
+ // the opposite of `missing`, which asks what THIS page needs.
573
+ //
574
+ // Scoped, a shorter edition of a page looked broken: every
575
+ // section it does not use made the schema's keys for that
576
+ // section look dead, and one such page reported 118 of them
577
+ // while its longer sibling reported none. The document's only
578
+ // difference was using fewer sections.
579
+ const wide = await runtime.options.layouts.inspect(layoutId, { samples: 0 })
580
+ const anyLayout = new Set([
581
+ ...(wide.references?.contract?.meta ?? []),
582
+ ...observed,
583
+ ])
584
+ const readAnywhere = (k) => anyLayout.has(k)
585
+ || [...anyLayout].some(c => c.startsWith(`${k}.`) || c.startsWith(`${k}[`))
571
586
  drift = {
572
587
  schema: declaredSchema.name,
573
588
  readButNotDeclared: [...consumed].filter(k => k && !knows(k)).sort(),
574
- declaredButNotRead: [...req].filter(k => !isRead(k)).sort(),
589
+ declaredButNotRead: [...req].filter(k => !readAnywhere(k)).sort(),
575
590
  }
591
+
592
+ // And the same noise in the softer list: a key this page's
593
+ // layout cannot reach is not an omission, it is not applicable.
594
+ // Reporting 139 of them is the noise the scoping fix removed
595
+ // from `missing`, arriving by another route.
596
+ const reachable = (k) => consumed.has(k)
597
+ || [...consumed].some(c => c.startsWith(`${k}.`) || c.startsWith(`${k}[`))
598
+ missingOptional = missingOptional.filter(reachable)
576
599
  }
577
600
 
578
601
  // A declared section that resolved to no template under this
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mikser-io-layouts",
3
- "version": "2.11.1",
3
+ "version": "2.11.2",
4
4
  "description": "SSG-flavor task-production policy for mikser-io. Multi-match layout assignment, per-layout destinations, postprocess chain attachment, layout inspection.",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -373,6 +373,27 @@ describe('mikser_check_entity: with a declared schema', () => {
373
373
  `missingOptional: ${r.missingOptional.join(', ')}`)
374
374
  })
375
375
 
376
+ it('answers declaredButNotRead against ANY layout, not just this page', async () => {
377
+ // The mirror of the scoping fix. `missing` asks what THIS page needs,
378
+ // so it is scoped; "is this key read anywhere" is the opposite question
379
+ // and must not be. Scoped, a shorter edition of a page reported every
380
+ // key of every section it does not use as dead — 118 of them on a page
381
+ // whose only difference was using fewer sections than its sibling.
382
+ const r = await checkWithSchema('/documents/schemed.md')
383
+ assert.ok(!r.drift.declaredButNotRead.some(k => k.startsWith('hero.')),
384
+ `hero keys are read by a layout, just not this render: ${r.drift.declaredButNotRead.join(', ')}`)
385
+ })
386
+
387
+ it('does not list an optional key this page could not use anyway', async () => {
388
+ // Same noise by another route: a key outside what this page renders is
389
+ // not an omission, it is not applicable.
390
+ const r = await checkWithSchema('/documents/schemed.md')
391
+ for (const k of r.missingOptional) {
392
+ assert.ok(!/^(specs|series|results)\./.test(k),
393
+ `${k} belongs to a section this page does not render`)
394
+ }
395
+ })
396
+
376
397
  it('reports drift in both directions', async () => {
377
398
  const r = await checkWithSchema('/documents/schemed.md')
378
399
  assert.equal(r.drift.schema, 'article')