@hawkeyexl/manni 4.4.1 → 4.6.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/README.md +1 -1
- package/dist/batch-OZOACN4G.js +41 -0
- package/dist/build-Z5VOVADH.js +32 -0
- package/dist/calibrate-TZYT42DR.js +36 -0
- package/dist/capture-SL4MNDDP.js +34 -0
- package/dist/check-5OMA42Y6.js +26 -0
- package/dist/{check-HYNGXYJV.js → check-OAJWC3WD.js} +7 -5
- package/dist/{check-ASPIHA6B.js → check-PKY7KTQE.js} +13 -14
- package/dist/check-WB2QDHJQ.js +880 -0
- package/dist/check-WB2QDHJQ.js.map +1 -0
- package/dist/{chunk-MWJLZMBL.js → chunk-2JFPBZJK.js} +11 -11
- package/dist/{chunk-QQUKGCAJ.js → chunk-2KRB3EG7.js} +2 -2
- package/dist/{chunk-DXNZS72W.js → chunk-2M6DVNI5.js} +10 -6
- package/dist/{chunk-DXNZS72W.js.map → chunk-2M6DVNI5.js.map} +1 -1
- package/dist/{chunk-QZ6LRSNV.js → chunk-3NWX34ZI.js} +19 -19
- package/dist/{chunk-IDV6HJCB.js → chunk-5G53XATW.js} +4 -4
- package/dist/{chunk-M2JCK5F6.js → chunk-6KKZXB2O.js} +19 -6
- package/dist/chunk-6KKZXB2O.js.map +1 -0
- package/dist/{chunk-PNPQTHBT.js → chunk-733Y2STG.js} +2 -2
- package/dist/{chunk-WB3QM6PP.js → chunk-73TC4DYH.js} +332 -2522
- package/dist/chunk-73TC4DYH.js.map +1 -0
- package/dist/{chunk-EPH54CAY.js → chunk-7WRP5FFP.js} +4 -4
- package/dist/{chunk-NXV7WE2D.js → chunk-APKH2T6E.js} +29 -591
- package/dist/chunk-APKH2T6E.js.map +1 -0
- package/dist/{chunk-I2AH3CJJ.js → chunk-B3TS4WRM.js} +17 -15
- package/dist/{chunk-I2AH3CJJ.js.map → chunk-B3TS4WRM.js.map} +1 -1
- package/dist/chunk-BWCWTHYS.js +146 -0
- package/dist/chunk-BWCWTHYS.js.map +1 -0
- package/dist/{chunk-MMTSSTG7.js → chunk-C3B2VJNC.js} +2 -2
- package/dist/{chunk-PU6DFJMY.js → chunk-C73RSUIC.js} +4 -4
- package/dist/chunk-CU57HT2E.js +116 -0
- package/dist/chunk-CU57HT2E.js.map +1 -0
- package/dist/chunk-CWXZ2MRT.js +222 -0
- package/dist/chunk-CWXZ2MRT.js.map +1 -0
- package/dist/{chunk-GCQRPUSB.js → chunk-DC5DDJVE.js} +6 -6
- package/dist/{chunk-6OYEI2VV.js → chunk-ECVQNGTH.js} +3 -3
- package/dist/chunk-FLAO4ZS3.js +502 -0
- package/dist/chunk-FLAO4ZS3.js.map +1 -0
- package/dist/chunk-FQGLRJGX.js +174 -0
- package/dist/chunk-FQGLRJGX.js.map +1 -0
- package/dist/{chunk-7UKO3ASZ.js → chunk-GAJIJKET.js} +3 -3
- package/dist/{chunk-6JSSEWBG.js → chunk-GREQKO6M.js} +202 -54
- package/dist/chunk-GREQKO6M.js.map +1 -0
- package/dist/chunk-HX44GB4Z.js +30 -0
- package/dist/chunk-HX44GB4Z.js.map +1 -0
- package/dist/{chunk-4IUC2MNL.js → chunk-IY7NYNPZ.js} +9 -11
- package/dist/{chunk-4IUC2MNL.js.map → chunk-IY7NYNPZ.js.map} +1 -1
- package/dist/{chunk-57NEQRVO.js → chunk-KCOFEWV5.js} +8 -6
- package/dist/{chunk-57NEQRVO.js.map → chunk-KCOFEWV5.js.map} +1 -1
- package/dist/chunk-M2RLHZ4J.js +849 -0
- package/dist/chunk-M2RLHZ4J.js.map +1 -0
- package/dist/{chunk-NLXTXE5Y.js → chunk-M6GSS72T.js} +185 -33
- package/dist/chunk-M6GSS72T.js.map +1 -0
- package/dist/{chunk-YTURO7SI.js → chunk-MHM4QEBV.js} +4 -4
- package/dist/{chunk-RL5XWQOL.js → chunk-MOWMCEOJ.js} +143 -54
- package/dist/chunk-MOWMCEOJ.js.map +1 -0
- package/dist/{chunk-C4SQM22E.js → chunk-MWBJ3KTF.js} +13 -11
- package/dist/chunk-MWBJ3KTF.js.map +1 -0
- package/dist/chunk-N7JSEDSC.js +233 -0
- package/dist/chunk-N7JSEDSC.js.map +1 -0
- package/dist/{chunk-JCDXE76J.js → chunk-NBMPHD4I.js} +2 -2
- package/dist/{chunk-37LP5HMZ.js → chunk-NHHOPZRA.js} +12 -10
- package/dist/{chunk-37LP5HMZ.js.map → chunk-NHHOPZRA.js.map} +1 -1
- package/dist/{chunk-YB4IBW3M.js → chunk-NTWW7J76.js} +2 -2
- package/dist/{chunk-UJCVAWP7.js → chunk-PCFG7E6B.js} +3 -3
- package/dist/{chunk-UJCVAWP7.js.map → chunk-PCFG7E6B.js.map} +1 -1
- package/dist/{chunk-FBEQCK47.js → chunk-PL4UAF4S.js} +73 -1304
- package/dist/chunk-PL4UAF4S.js.map +1 -0
- package/dist/chunk-QCHVR4ZM.js +286 -0
- package/dist/chunk-QCHVR4ZM.js.map +1 -0
- package/dist/{chunk-PIKOVN6W.js → chunk-QW77LCOU.js} +10 -10
- package/dist/{chunk-2B7ZNTPV.js → chunk-SM6NOMJS.js} +2 -2
- package/dist/chunk-SWSTHZBI.js +2464 -0
- package/dist/chunk-SWSTHZBI.js.map +1 -0
- package/dist/{chunk-JXLTXMJ7.js → chunk-T6SYGLWR.js} +3 -3
- package/dist/{chunk-CK7SKVHR.js → chunk-TBAMBLF3.js} +3 -12
- package/dist/chunk-TBAMBLF3.js.map +1 -0
- package/dist/chunk-TH4JVQPF.js +133 -0
- package/dist/chunk-TH4JVQPF.js.map +1 -0
- package/dist/{chunk-QRWGPQKO.js → chunk-TLXE7LYK.js} +4 -4
- package/dist/{chunk-M3W7J6MU.js → chunk-TUAAR3MM.js} +3280 -283
- package/dist/chunk-TUAAR3MM.js.map +1 -0
- package/dist/{chunk-SKSDRUUK.js → chunk-UAKNZVCD.js} +4 -4
- package/dist/{chunk-YJOGUXGP.js → chunk-UJSGS2Y5.js} +8 -6
- package/dist/{chunk-YJOGUXGP.js.map → chunk-UJSGS2Y5.js.map} +1 -1
- package/dist/{chunk-UQISLDAV.js → chunk-UWQ2UVHE.js} +8 -6
- package/dist/{chunk-UQISLDAV.js.map → chunk-UWQ2UVHE.js.map} +1 -1
- package/dist/chunk-WQWKYAAK.js +86 -0
- package/dist/chunk-WQWKYAAK.js.map +1 -0
- package/dist/{chunk-LJ2RDH3F.js → chunk-XG6PVB5S.js} +1 -23
- package/dist/chunk-XG6PVB5S.js.map +1 -0
- package/dist/{chunk-Q35YIDBV.js → chunk-XKBEHKWO.js} +29 -264
- package/dist/chunk-XKBEHKWO.js.map +1 -0
- package/dist/chunk-XPEWUK7J.js +532 -0
- package/dist/chunk-XPEWUK7J.js.map +1 -0
- package/dist/{chunk-MYMBCTDE.js → chunk-XXDXIIQ4.js} +2 -2
- package/dist/chunk-YGFIQ6Y5.js +17 -0
- package/dist/chunk-YGFIQ6Y5.js.map +1 -0
- package/dist/chunk-YLK2J5YK.js +610 -0
- package/dist/chunk-YLK2J5YK.js.map +1 -0
- package/dist/{chunk-3VK37OR2.js → chunk-Z4IZGEM3.js} +16 -12
- package/dist/{chunk-3VK37OR2.js.map → chunk-Z4IZGEM3.js.map} +1 -1
- package/dist/{cli-6HIDIFVT.js → cli-6EWVMEN6.js} +5 -3
- package/dist/{cli-6HIDIFVT.js.map → cli-6EWVMEN6.js.map} +1 -1
- package/dist/{cli-VI7VHWNZ.js → cli-6H7HVDMQ.js} +113 -20
- package/dist/{cli-VI7VHWNZ.js.map → cli-6H7HVDMQ.js.map} +1 -1
- package/dist/{cli-RPM5PELX.js → cli-EPVZHAZS.js} +24 -20
- package/dist/cli-EPVZHAZS.js.map +1 -0
- package/dist/{cli-MN7PYMBI.js → cli-LUCSGTVI.js} +17 -19
- package/dist/{cli-MN7PYMBI.js.map → cli-LUCSGTVI.js.map} +1 -1
- package/dist/{cli-LFP5ZGYS.js → cli-NIG4N3XM.js} +16 -15
- package/dist/{cli-LFP5ZGYS.js.map → cli-NIG4N3XM.js.map} +1 -1
- package/dist/{cli-PYPX6O6E.js → cli-PSKNB66T.js} +225 -58
- package/dist/cli-PSKNB66T.js.map +1 -0
- package/dist/{cli-3BIBYHFK.js → cli-UO4NHIB3.js} +17 -17
- package/dist/{cli-6UB5N6CU.js → cli-UQ7A3YA2.js} +17 -18
- package/dist/{cli-6UB5N6CU.js.map → cli-UQ7A3YA2.js.map} +1 -1
- package/dist/{cli-673OTRGE.js → cli-YHYDLQAF.js} +10 -10
- package/dist/cli.js +11 -11
- package/dist/config-P4HDNTYD.js +26 -0
- package/dist/conformance-ZFCMKM6M.js +18 -0
- package/dist/docmeta.js +9 -9
- package/dist/github-7ZCH5PSO.js +26 -0
- package/dist/github-POT6724K.js +31 -0
- package/dist/host-6GURH5HE.js +23 -0
- package/dist/index.d.ts +102 -12
- package/dist/index.js +185 -171
- package/dist/index.js.map +1 -1
- package/dist/{json-SY7KLNC7.js → json-KT2K62L5.js} +12 -13
- package/dist/lint-5AQ5C2BV.js +29 -0
- package/dist/list-5JZKX2NK.js +28 -0
- package/dist/list-SWPFXQMU.js +30 -0
- package/dist/{page-KSGV5RD4.js → page-UPSXRP75.js} +11 -12
- package/dist/prepare-6GNEWCNH.js +155 -0
- package/dist/prepare-6GNEWCNH.js.map +1 -0
- package/dist/{pretty-CXSDXNAS.js → pretty-Q6FQAOK4.js} +13 -14
- package/dist/{pretty-A5EGTN35.js → pretty-SQRPFPSQ.js} +12 -13
- package/dist/provider-AMGRDY6V.js +34 -0
- package/dist/release-IECYCLTD.js +36 -0
- package/dist/release-IECYCLTD.js.map +1 -0
- package/dist/{reporters-HUY7UXFS.js → reporters-45MMC2ID.js} +13 -13
- package/dist/{reporters-K2VUKSAK.js → reporters-XUV4MM64.js} +7 -5
- package/dist/reporters-XUV4MM64.js.map +1 -0
- package/dist/run-KMWY2IAN.js +32 -0
- package/dist/run-KMWY2IAN.js.map +1 -0
- package/dist/{term-BIQUPMOR.js → term-PCJUCWNF.js} +16 -17
- package/dist/{term-BIQUPMOR.js.map → term-PCJUCWNF.js.map} +1 -1
- package/dist/validate-IMNCZNWG.js +17 -0
- package/dist/validate-IMNCZNWG.js.map +1 -0
- package/package.json +2 -2
- package/plugin/manni/.claude-plugin/plugin.json +1 -1
- package/plugin/manni/hooks/hooks.json +47 -0
- package/dist/batch-GFNLTGOH.js +0 -36
- package/dist/build-COYIQ25L.js +0 -31
- package/dist/calibrate-MDBLJKEE.js +0 -31
- package/dist/capture-LRML2PKV.js +0 -32
- package/dist/check-EDLBYL5N.js +0 -27
- package/dist/chunk-6JSSEWBG.js.map +0 -1
- package/dist/chunk-A5ULMVHQ.js +0 -164
- package/dist/chunk-A5ULMVHQ.js.map +0 -1
- package/dist/chunk-C4SQM22E.js.map +0 -1
- package/dist/chunk-CK7SKVHR.js.map +0 -1
- package/dist/chunk-FBEQCK47.js.map +0 -1
- package/dist/chunk-LJ2RDH3F.js.map +0 -1
- package/dist/chunk-M2JCK5F6.js.map +0 -1
- package/dist/chunk-M3W7J6MU.js.map +0 -1
- package/dist/chunk-NLXTXE5Y.js.map +0 -1
- package/dist/chunk-NXV7WE2D.js.map +0 -1
- package/dist/chunk-Q35YIDBV.js.map +0 -1
- package/dist/chunk-RL5XWQOL.js.map +0 -1
- package/dist/chunk-TK3FC4RF.js +0 -3090
- package/dist/chunk-TK3FC4RF.js.map +0 -1
- package/dist/chunk-TU2WUBVZ.js +0 -2
- package/dist/chunk-WB3QM6PP.js.map +0 -1
- package/dist/cli-PYPX6O6E.js.map +0 -1
- package/dist/cli-RPM5PELX.js.map +0 -1
- package/dist/github-6QMYOHC3.js +0 -27
- package/dist/github-SXPGP5DB.js +0 -32
- package/dist/lint-ASMJLLPA.js +0 -28
- package/dist/list-KZNVTNVC.js +0 -31
- package/dist/list-Q57YTFUQ.js +0 -29
- package/dist/run-3DYJNRIG.js +0 -33
- package/dist/validate-53RKM2XG.js +0 -16
- /package/dist/{batch-GFNLTGOH.js.map → batch-OZOACN4G.js.map} +0 -0
- /package/dist/{build-COYIQ25L.js.map → build-Z5VOVADH.js.map} +0 -0
- /package/dist/{calibrate-MDBLJKEE.js.map → calibrate-TZYT42DR.js.map} +0 -0
- /package/dist/{capture-LRML2PKV.js.map → capture-SL4MNDDP.js.map} +0 -0
- /package/dist/{check-ASPIHA6B.js.map → check-5OMA42Y6.js.map} +0 -0
- /package/dist/{check-EDLBYL5N.js.map → check-OAJWC3WD.js.map} +0 -0
- /package/dist/{check-HYNGXYJV.js.map → check-PKY7KTQE.js.map} +0 -0
- /package/dist/{chunk-MWJLZMBL.js.map → chunk-2JFPBZJK.js.map} +0 -0
- /package/dist/{chunk-QQUKGCAJ.js.map → chunk-2KRB3EG7.js.map} +0 -0
- /package/dist/{chunk-QZ6LRSNV.js.map → chunk-3NWX34ZI.js.map} +0 -0
- /package/dist/{chunk-IDV6HJCB.js.map → chunk-5G53XATW.js.map} +0 -0
- /package/dist/{chunk-PNPQTHBT.js.map → chunk-733Y2STG.js.map} +0 -0
- /package/dist/{chunk-EPH54CAY.js.map → chunk-7WRP5FFP.js.map} +0 -0
- /package/dist/{chunk-MMTSSTG7.js.map → chunk-C3B2VJNC.js.map} +0 -0
- /package/dist/{chunk-PU6DFJMY.js.map → chunk-C73RSUIC.js.map} +0 -0
- /package/dist/{chunk-GCQRPUSB.js.map → chunk-DC5DDJVE.js.map} +0 -0
- /package/dist/{chunk-6OYEI2VV.js.map → chunk-ECVQNGTH.js.map} +0 -0
- /package/dist/{chunk-7UKO3ASZ.js.map → chunk-GAJIJKET.js.map} +0 -0
- /package/dist/{chunk-YTURO7SI.js.map → chunk-MHM4QEBV.js.map} +0 -0
- /package/dist/{chunk-JCDXE76J.js.map → chunk-NBMPHD4I.js.map} +0 -0
- /package/dist/{chunk-YB4IBW3M.js.map → chunk-NTWW7J76.js.map} +0 -0
- /package/dist/{chunk-PIKOVN6W.js.map → chunk-QW77LCOU.js.map} +0 -0
- /package/dist/{chunk-2B7ZNTPV.js.map → chunk-SM6NOMJS.js.map} +0 -0
- /package/dist/{chunk-JXLTXMJ7.js.map → chunk-T6SYGLWR.js.map} +0 -0
- /package/dist/{chunk-QRWGPQKO.js.map → chunk-TLXE7LYK.js.map} +0 -0
- /package/dist/{chunk-SKSDRUUK.js.map → chunk-UAKNZVCD.js.map} +0 -0
- /package/dist/{chunk-MYMBCTDE.js.map → chunk-XXDXIIQ4.js.map} +0 -0
- /package/dist/{cli-3BIBYHFK.js.map → cli-UO4NHIB3.js.map} +0 -0
- /package/dist/{chunk-TU2WUBVZ.js.map → cli-YHYDLQAF.js.map} +0 -0
- /package/dist/{cli-673OTRGE.js.map → config-P4HDNTYD.js.map} +0 -0
- /package/dist/{github-6QMYOHC3.js.map → conformance-ZFCMKM6M.js.map} +0 -0
- /package/dist/{github-SXPGP5DB.js.map → github-7ZCH5PSO.js.map} +0 -0
- /package/dist/{json-SY7KLNC7.js.map → github-POT6724K.js.map} +0 -0
- /package/dist/{lint-ASMJLLPA.js.map → host-6GURH5HE.js.map} +0 -0
- /package/dist/{list-KZNVTNVC.js.map → json-KT2K62L5.js.map} +0 -0
- /package/dist/{list-Q57YTFUQ.js.map → lint-5AQ5C2BV.js.map} +0 -0
- /package/dist/{page-KSGV5RD4.js.map → list-5JZKX2NK.js.map} +0 -0
- /package/dist/{pretty-A5EGTN35.js.map → list-SWPFXQMU.js.map} +0 -0
- /package/dist/{pretty-CXSDXNAS.js.map → page-UPSXRP75.js.map} +0 -0
- /package/dist/{reporters-HUY7UXFS.js.map → pretty-Q6FQAOK4.js.map} +0 -0
- /package/dist/{reporters-K2VUKSAK.js.map → pretty-SQRPFPSQ.js.map} +0 -0
- /package/dist/{run-3DYJNRIG.js.map → provider-AMGRDY6V.js.map} +0 -0
- /package/dist/{validate-53RKM2XG.js.map → reporters-45MMC2ID.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/meta/commands/validate.ts","../src/meta/core/external-metadata.ts","../src/shared/manifest-cas.ts","../src/meta/core/external-metadata-fetch.ts","../src/shared/encryption-key.ts","../src/shared/write-file.ts","../src/meta/core/encrypted.ts","../src/meta/core/location.ts","../src/meta/core/validator.ts","../src/meta/core/graph-output.ts","../src/meta/core/page-marks.ts","../src/meta/core/relocation.ts","../src/meta/core/collections.ts","../src/meta/core/projection.ts","../src/meta/core/external-metadata-write.ts","../src/meta/core/derive/provenance.ts","../src/shared/pin.ts","../src/meta/core/derive/config.ts","../src/meta/core/derive/index.ts","../src/meta/core/derive/cache.ts","../src/meta/core/derive/codeowners.ts","../src/meta/core/derive/spawn.ts","../src/meta/core/derive/command.ts","../src/meta/core/derive/reviews.ts","../src/meta/core/derive/git.ts","../src/shared/concurrency.ts","../src/meta/core/derive/table.ts","../src/meta/core/checks.ts","../src/meta/core/derive/provenance-place.ts","../src/shared/cli-options.ts"],"sourcesContent":["/**\n * `validate` command core. Resolves targets, extracts metadata, resolves a\n * schema set per file, validates, and returns structured results. Kept free of\n * CLI/IO plumbing so it can be tested directly.\n */\nimport { readFile } from \"node:fs/promises\";\nimport {\n loadExternalMetadata,\n mergeWithMarks,\n orphanEntries,\n orphanError,\n orphanJoins,\n externalMetadataJoin,\n externalMetadataPointer,\n EXTERNAL_DUPLICATE_SCHEMA,\n EXTERNAL_KEYWORD,\n EXTERNAL_OWNED_SCHEMA,\n PATH_JOIN,\n type MergedMetadata,\n} from \"../core/external-metadata.js\";\nimport {\n LOCATION_EXTERNAL_SCHEMA,\n LOCATION_FINDING_KEYWORD,\n LOCATION_PAGE_SCHEMA,\n} from \"../core/location.js\";\nimport { pageMarks } from \"../core/page-marks.js\";\nimport {\n keyHome,\n relocationContext,\n type RelocationContext,\n} from \"../core/relocation.js\";\nimport { resolve, extname } from \"node:path\";\nimport {\n DocmetaError,\n isErrorSeverity,\n type FieldError,\n type RunSummary,\n type ValidationResult,\n} from \"../types.js\";\nimport {\n canonicalSchemaRef,\n DEFAULT_BASELINE_PATH,\n LEGACY_BASELINE_PATH,\n type FingerprintContext,\n resolveBaselineRequest,\n settleBaseline,\n} from \"../core/baseline.js\";\nimport {\n extractorByName,\n extractorForExtension,\n supportedExtensions,\n} from \"../extractors/index.js\";\nimport {\n assertNonEmpty,\n gitignoreOptions,\n resolveTargetSet,\n STDIN_LABEL,\n STDIN_TOKEN,\n} from \"../core/load-files.js\";\nimport {\n resolveRunConfig,\n schemaTrustRoot,\n type ConfigNotice,\n} from \"../core/config.js\";\nimport { memberOf, retainMembers } from \"../core/collections.js\";\nimport {\n collectSchemaPins,\n resolveSchemaSetWithSource,\n FILE_SCHEMA_KEY,\n type ResolvedSchemaSet,\n resolveElements,\n} from \"../core/resolve-schema.js\";\nimport { Validator } from \"../core/validator.js\";\nimport { schemaLoadOptions } from \"../core/schema-registry.js\";\nimport { runChecks, type CheckEntry } from \"../core/checks.js\";\nimport {\n encryptionFindings,\n encryptionView,\n isAtOrUnder,\n lazyKey,\n pointerOf,\n redactedDerived,\n settleFindings,\n unverifiedWarning,\n} from \"../core/encrypted.js\";\nimport {\n assertSourcesAvailable,\n deriveMetadata,\n type DeriveResult,\n} from \"../core/derive/index.js\";\nimport { commandsOf, machinesOf } from \"../core/derive/config.js\";\nimport {\n compareProvenance,\n provenanceEntries,\n provenanceFindings,\n} from \"../core/derive/provenance.js\";\nimport { readerManifests, readerPlace, stampManifests } from \"../core/derive/provenance-place.js\";\nimport {\n fieldsForSql,\n mentionsDerived,\n mentionsResolved,\n} from \"../core/derive/table.js\";\nimport {\n compareDerived,\n derivableFields,\n DERIVE_SOURCES,\n deriveCovers,\n managedFields,\n PROVENANCE_FIELD,\n STAMPED_DATE_FIELDS,\n staleFindings,\n type DerivedRecord,\n type DeriveInput,\n} from \"../core/derive/types.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { STDIN_REQUIRES_AS } from \"../../shared/cli-options.js\";\n\nexport interface ValidateOptions {\n inputs: string[];\n cliSchemas?: string[];\n exts?: string[];\n exclude?: string[];\n /** `--as` format override (extractor name). */\n as?: string;\n configPath?: string;\n /** `--no-config`: skip config discovery and use the built-in defaults. */\n noConfig?: boolean;\n /**\n * `--collection <name>`, repeatable: run over the named configured\n * collections instead of every declared one (proposal 0041). Cannot be\n * combined with positional paths; `-` is allowed beside it.\n */\n collections?: string[];\n cwd?: string;\n /** Content for the `-` (stdin) input, injected by the CLI/tests. */\n stdinContent?: string;\n /** Permit an input set that resolves to zero files (see `assertNonEmpty`). */\n allowEmpty?: boolean;\n /**\n * `--no-gitignore` (false). Absent leaves config `respectGitignore:` in\n * charge, which itself defaults to on.\n */\n respectGitignore?: boolean;\n /** Diagnostics for the user; the CLI writes these to stderr. */\n onNotice?: (message: string) => void;\n /**\n * `--baseline [path]`: compare findings against a recorded baseline and fail\n * only on new ones. A string is a path relative to `cwd`; `true` means the\n * default path; `false` is `--no-baseline`, which suppresses a baseline the\n * config supplied. Absent means \"whatever the config says\".\n */\n baseline?: string | boolean;\n /**\n * `--write-baseline [path]`: record this run's findings as the baseline\n * instead of comparing against one. Wins over `baseline`.\n */\n writeBaseline?: string | boolean;\n /** Called once when a config governs the run, so the CLI can report it. */\n onConfigLoaded?: (info: ConfigNotice) => void;\n /**\n * `--offline`: never fetch a remote schema. Absent leaves config `offline:`\n * in charge, which itself defaults to off.\n */\n offline?: boolean;\n /**\n * `--no-cache` (false): ask GitHub or GitLab again rather than reading the\n * review cache. It reaches the comparison and any check reading the\n * `derived` table; absent leaves the cache on.\n */\n cache?: boolean;\n /**\n * `--no-checks` (false): skip the config's named corpus checks for this\n * run. Absent leaves them on — they still only run when the resolved file\n * set is the config-resolved corpus (proposal 0026).\n */\n checks?: boolean;\n /**\n * The environment `MANNI_ENCRYPTION_KEY` is read from (proposal 0045).\n * Defaults to `process.env`; tests pass their own so a developer's key is\n * never read.\n */\n env?: NodeJS.ProcessEnv;\n /**\n * `--no-derive` (false): skip comparing each managed field (`derive.fields`\n * in the config, proposal 0040) with what the evidence says. Absent leaves\n * the comparison on whenever `derive:` is configured — on scoped runs too,\n * since it is per file rather than a corpus rule.\n */\n derive?: boolean;\n /** The clock an uncommitted body change is dated by. Test seam; default `new Date()`. */\n now?: () => Date;\n /**\n * Leave out a file judged by the built-in default set alone: no `$schema`\n * of its own, and no `schemas:` or `overrides:` entry covering it. Such a\n * file gets no result and is not counted. `manni check` sets this, because\n * a default it would apply is not something the project set up.\n */\n skipDefaultOnly?: boolean;\n}\n\nexport interface ValidateRun {\n results: ValidationResult[];\n summary: RunSummary;\n /**\n * Where the run stood: the working directory, the directory canonical paths\n * are measured from, and the directory `results[].file` labels are relative\n * to.\n *\n * Returned rather than kept private because a `ValidationResult.file` is only\n * meaningful *with* it. A reporter that has to name a file the same way from\n * anywhere — SARIF, whose `artifactLocation.uri` GitHub resolves against the\n * repository root — cannot reconstruct this after the fact, and guessing puts\n * it in the same false-green trap the baseline's canonical keys exist to\n * avoid.\n */\n frame: FingerprintContext;\n}\n\n/**\n * A violation docmeta raises itself rather than one Ajv produced.\n *\n * Two different failures land here and they are not the same thing: the\n * document's metadata block could not be parsed (`parse`), or a schema set\n * could not be resolved for it (`schema`). `keyword` is what tells them apart\n * downstream — the `schema` field stays `\"(parse)\"` for both, because it is the\n * documented literal machine consumers already match on.\n */\nfunction parseErrorResult(\n file: string,\n format: string,\n message: string,\n keyword: \"parse\" | \"schema\",\n): ValidationResult {\n const err: FieldError = {\n schema: \"(parse)\",\n instancePath: \"\",\n message,\n keyword,\n };\n return { file, format, ok: false, schemas: [], errors: [err] };\n}\n\n/**\n * What the derived comparison needs from one file's encryption view\n * (proposals 0040 and 0045), kept from the per-file loop for after it.\n */\ninterface ManagedView {\n /** The metadata with every readable encrypted value decrypted. A copy. */\n data: Record<string, unknown>;\n /** The pointers the schema marks, over the metadata as the page holds it. */\n marked: readonly string[];\n /** Marked pointers holding a ciphertext no key could read. */\n hidden: readonly string[];\n /** The file's schema set, to read the mark of a field the page lacks. */\n refs: string[];\n /** Where a value a manifest supplied lives, so a stale finding names its line (0047). */\n locate: (pointer: string) => { file: string; line?: number } | undefined;\n}\n\n/**\n * Run `fn` at most once and hand every caller the same promise, rejection\n * included: a derivation that failed for the checks has failed for the\n * comparison too, and must not be retried against the same evidence.\n */\nfunction once<T>(fn: () => Promise<T>): () => Promise<T> {\n let pending: Promise<T> | undefined;\n return () => {\n pending ??= fn();\n return pending;\n };\n}\n\nexport async function runValidate(\n opts: ValidateOptions,\n): Promise<ValidateRun> {\n const cwd = opts.cwd ?? process.cwd();\n\n // Explicit CLI inputs win, else config `paths:`; `base` is whichever of the\n // two directories those inputs were written relative to.\n const run = await resolveRunConfig({\n cwd,\n configPath: opts.configPath,\n noConfig: opts.noConfig,\n inputs: opts.inputs,\n ...(opts.collections !== undefined\n ? { collections: opts.collections }\n : {}),\n onConfigLoaded: opts.onConfigLoaded,\n });\n const {\n config,\n inputs,\n base,\n configDir,\n collections,\n declaredCollections,\n fromCollections,\n configFile,\n } = run;\n /** The collections one label belongs to, computed once per file. */\n const membersFor = (label: string): string[] =>\n memberOf(collections, configDir ?? cwd, base, label);\n const usingStdin = inputs.includes(STDIN_TOKEN);\n\n if (inputs.length === 0) {\n throw new DocmetaError(\n \"No files to validate. Pass paths/globs, or declare a collection under `collections:` in manni.config.yaml.\",\n );\n }\n\n // Pick an explicit extractor for `--as`, validating it up front.\n const forcedExtractor = opts.as ? extractorByName(opts.as) : undefined;\n if (opts.as && !forcedExtractor) {\n throw new DocmetaError(\n `Unknown format \"${opts.as}\". Supported extensions: ${supportedExtensions().join(\", \")}.`,\n );\n }\n\n const exts =\n opts.exts ?? (forcedExtractor ? forcedExtractor.extensions : undefined);\n\n const fileInputs = inputs.filter((i) => i !== STDIN_TOKEN);\n const allowEmpty = opts.allowEmpty ?? config?.allowEmpty;\n // Only `--exclude`. A collection's `exclude:` governs *membership*, not the\n // walk of a path someone typed (0041 rule 3): the tool has no basis to pick\n // which collection's exclusions to honour once there are several.\n const exclude = opts.exclude ?? [];\n const { files: walked, gitignoreSkipped } = await resolveTargetSet({\n inputs: fileInputs,\n exts,\n exclude,\n cwd: base,\n allowEmpty,\n ...gitignoreOptions({\n flag: opts.respectGitignore,\n configured: config?.respectGitignore,\n onNotice: opts.onNotice,\n }),\n });\n // Rule 9: the walk applied only the family ignores and `--exclude`, so it saw\n // just the first half of each collection's statement. Narrow it to actual\n // members, or a collection's `exclude:` would shape its SQL view and not what\n // a bare run reads. Skipped for typed paths: those are the operator's (rule 3).\n const files = fromCollections ? retainMembers(walked, membersFor) : walked;\n assertNonEmpty({\n files,\n inputs: fileInputs,\n usingStdin,\n allowEmpty,\n exclude,\n exts,\n gitignoreSkipped,\n action: \"validated\",\n });\n\n // Settled once per run, not per file: finding it is a filesystem walk, and\n // every file in one run shares the same repository.\n const trustRoot = schemaTrustRoot(cwd, configDir);\n\n // External metadata (0037), read once per run: a manifest the config names\n // that cannot be read is the run's problem, not a document's.\n const externalMetadata = await loadExternalMetadata(collections, {\n configDir: configDir ?? cwd,\n base,\n offline: opts.offline ?? config?.offline ?? false,\n // A `{page}` manifest (0058) is read for exactly the pages this run reads.\n pages: files.map((file) => resolve(base, file)),\n });\n\n const validator = new Validator(\n schemaLoadOptions({\n // The config's directory when a config governs the run, so one project\n // keeps one cache no matter which directory the command was run from.\n root: configDir ?? cwd,\n // A relative file ref belongs to the run's directory, not the cache root.\n fileBase: cwd,\n ttlHours: config?.schemaCache?.ttlHours,\n offline: opts.offline ?? config?.offline,\n // Built from the rebased config, so a pinned local ref is keyed by the\n // same absolute spelling `resolveSchemaSet` will hand to `loadSchema`.\n pins: collectSchemaPins(config),\n registered: config?.registered,\n }),\n );\n // What each page's schemas mark external, for a keyless manifest (0068).\n const marks = pageMarks({\n validator,\n config,\n cwd,\n trustRoot,\n ...(opts.cliSchemas !== undefined ? { cliSchemas: opts.cliSchemas } : {}),\n });\n // Where a misplaced value could go (proposal 0047), asked only to word a\n // `location:external` finding. Built on first use: most runs mark nothing.\n let relocation: RelocationContext | undefined;\n const relocationCtx = (): RelocationContext =>\n (relocation ??= relocationContext(run, {\n cwd,\n targets: fromCollections ? [] : opts.inputs,\n validator,\n ...(opts.noConfig !== undefined ? { noConfig: opts.noConfig } : {}),\n ...(opts.env !== undefined ? { env: opts.env } : {}),\n }));\n // Schema refs in a location message are named the way a rule id names them,\n // not by the absolute path a rebased config holds.\n const refFrame: FingerprintContext = { cwd, base: configDir ?? cwd, runBase: base };\n\n /**\n * The `location:external` and `location:page` warnings for one document\n * (proposal 0047), judged over `data`, the merged metadata validation saw.\n *\n * - `location:external`: a key the page itself holds, which its schemas\n * prefer in external metadata. Not for a key a manifest of the page's\n * collections owns (`external:owned` already errors there), and not for\n * the join field of a field-joined manifest, which is how the page names\n * its entry and so has to stay in the page.\n * - `location:page`: a key a manifest supplied, which its schemas prefer on\n * the page. Filed at the manifest line, as manifest findings are.\n *\n * In the merged data's key order, the page's own keys first.\n */\n const locationFindings = async (\n label: string,\n own: Readonly<Record<string, unknown>>,\n data: Record<string, unknown>,\n refs: string[],\n members: readonly string[],\n merged: MergedMetadata,\n lineFor: (pointer: string) => number | undefined,\n ): Promise<FieldError[]> => {\n const preferences = await validator.locationPreferences(data, refs);\n if (preferences.size === 0) return [];\n const owned = new Set(merged.collisions.map((c) => c.key));\n // Every declared collection the page is in, as relocate reads them: a\n // `--collection` run that leaves one out still leaves its join in place.\n const declaredMembers =\n declaredCollections === collections\n ? members\n : memberOf(declaredCollections, configDir ?? cwd, base, label);\n const joins = new Set(\n declaredCollections\n .filter((c) => declaredMembers.includes(c.name))\n .flatMap((c) => c.externalMetadata.map(externalMetadataJoin))\n .filter((join) => join !== PATH_JOIN),\n );\n const findings: FieldError[] = [];\n for (const key of Object.keys(data)) {\n const preference = preferences.get(key);\n if (preference === undefined) continue;\n const ref = canonicalSchemaRef(preference.schema, refFrame);\n const pointer = externalMetadataPointer(key);\n const common = {\n keyword: LOCATION_FINDING_KEYWORD,\n subject: key,\n instancePath: pointer,\n severity: \"warning\" as const,\n };\n if (Object.hasOwn(own, key)) {\n if (preference.location !== \"external\" || owned.has(key) || joins.has(key)) continue;\n const line = lineFor(key);\n const none = await homeless(label, own, key);\n findings.push({\n schema: LOCATION_EXTERNAL_SCHEMA,\n ...common,\n // relocate refuses --no-config (U2), so it is no answer there.\n // Nor is it one for stdin, which relocate refuses: no advice there.\n message: opts.noConfig\n ? `\"${key}\" is stored in the page; ${ref} prefers external metadata, and --no-config leaves it no manifest.`\n : label === STDIN_LABEL\n ? `\"${key}\" is stored in the page; ${ref} prefers external metadata.`\n : none > 0\n ? `\"${key}\" is stored in the page; ${ref} prefers external metadata, and this document is in none of the ${String(none)} collections.`\n : `\"${key}\" is stored in the page; ${ref} prefers external metadata. Run manni meta relocate.`,\n ...(line != null ? { line } : {}),\n });\n continue;\n }\n if (preference.location !== \"page\") continue;\n const at = merged.locate(pointer);\n if (at === undefined) continue;\n findings.push({\n schema: LOCATION_PAGE_SCHEMA,\n ...common,\n // A fetched manifest cannot give a value up, so relocate is no\n // answer; the value moves in the repository that serves it.\n message: /^https?:\\/\\//.test(at.file)\n ? `\"${key}\" is stored in manifest ${at.file}; ${ref} prefers the page, and a fetched manifest cannot be written. Move it in that repository.`\n : `\"${key}\" is stored in manifest ${at.file}; ${ref} prefers the page. Run manni meta relocate.`,\n file: at.file,\n ...(at.line != null ? { line: at.line } : {}),\n });\n }\n return findings;\n };\n\n /**\n * How many collections a page is in none of, when that leaves `key` no\n * possible home (several declared, the page in none); otherwise 0. With no\n * collections, or one the page is outside, relocate can still give it one,\n * and `--no-config` is V1 too: the finding says what to run, and relocate's\n * own refusal says why it cannot. Stdin is never homeless.\n */\n const homeless = async (label: string, own: Readonly<Record<string, unknown>>, key: string): Promise<number> => {\n if (label === STDIN_LABEL) return 0;\n const home = await keyHome(relocationCtx(), label, own, key);\n return home.kind === \"unowned\" &&\n home.home.kind === \"none\" &&\n home.home.reason === \"collections\" &&\n home.home.collections > 1\n ? home.home.collections\n : 0;\n };\n\n const results: ValidationResult[] = [];\n /** Files `skipDefaultOnly` left out, so a corpus check's finding on one is dropped with it. */\n const skippedDefaultOnly = new Set<string>();\n /** Whether the config alone gives `label` only the built-in default set. */\n const defaultOnly = (label: string, members: readonly string[]): boolean => {\n try {\n return (\n resolveSchemaSetWithSource({\n filePath: label,\n fileSchema: undefined,\n cliSchemas: opts.cliSchemas,\n config,\n memberOf: members,\n fileBase: cwd,\n trustRoot,\n }).source === \"default\"\n );\n } catch {\n return false;\n }\n };\n // Field-joined entries each document matched (0039), keyed by field then\n // value: the duplicate finding and the post-loop orphan check both need\n // to know which documents claimed which value.\n const joinHits = new Map<\n string,\n Map<string, { label: string; line?: number; file: string; shown: string }[]>\n >();\n // Corpus checks (0026) run only when the resolved file set IS the\n // config-resolved corpus — an invariant, not a flag list: any CLI reshaping\n // of the input set (positional paths, stdin, --as/--ext, --exclude,\n // --no-gitignore) disqualifies the run, because a corpus rule computed over\n // half a corpus reports wrong answers. `--collection` is the same reshaping\n // by name (0041 rule 11): every unselected collection's view holds only what\n // the run happened to load, so a `FROM blog` check would pass by having\n // nothing to fail on. `-s/--schema` disqualifies too even though the file\n // set is unchanged: a CLI schema override reshapes the corpus *contract* —\n // cliSchemas outranks every override, so every file is judged against a set\n // the config never assigned it, and a check written against the configured\n // contract would be reporting on a corpus that does not exist outside this\n // run. Config `exclude:` and `respectGitignore:` do not disqualify — they\n // *define* the corpus; the CLI flags redefine the run.\n const scopedToCollections = (opts.collections?.length ?? 0) > 0;\n const scopedByFlags =\n opts.inputs.length > 0 ||\n // redundant with inputs.length (stdin is an input) — kept as belt-and-suspenders\n usingStdin ||\n opts.as !== undefined ||\n opts.exts !== undefined ||\n (opts.exclude !== undefined && opts.exclude.length > 0) ||\n opts.respectGitignore !== undefined ||\n (opts.cliSchemas?.length ?? 0) > 0;\n // Corpus checks need the whole corpus: a reshaping flag disqualifies, and so\n // does narrowing by name, because every unselected collection's view then\n // holds only what the run happened to load (0041 rule 11).\n const scoped = scopedByFlags || scopedToCollections;\n const configuredChecks = config?.checks ?? [];\n\n // A manifest entry naming a document this run did not load (0037 rule 4):\n // 0014's named-file-that-is-not-there, and 0026 §4's row outside the run.\n // Only when the run is a corpus — a positional path or a reshaping flag means\n // the operator chose to look at part of it, and entries for the rest are\n // expected rather than orphaned.\n //\n // `--collection` is not such a reshaping. It makes each named collection the\n // corpus (0041 rule 6): the run loaded all of every collection it named, so\n // an entry of one of those pointing at a document that is not there is a\n // stale entry, and a CI job narrowed to one collection would otherwise lose\n // the check it relies on. Entries of unselected collections are skipped.\n if (!scopedByFlags) {\n const covered = scopedToCollections ? collections.map((c) => c.name) : undefined;\n const orphans = orphanEntries(externalMetadata, files, base, covered);\n if (orphans.length > 0) throw orphanError(orphans);\n }\n const checksWillRun =\n configuredChecks.length > 0 && opts.checks !== false && !scoped;\n // Every successful extraction, kept for the corpus checks (0026): the\n // projection they run over is these entries, exactly as `query` holds them.\n // 0021 measured that holding a docs corpus in memory is not the cost that\n // matters — but the common no-checks path should not retain every file's\n // extraction, so the list fills only when the checks will actually run.\n const checkEntries: CheckEntry[] = [];\n // The run's encryption key (proposal 0045), resolved the first time a\n // ciphertext needs it, and the encrypted values no key could verify.\n const encryptionKey = lazyKey(configFile, opts.env);\n let unverified = 0;\n\n // The derived channel (0040): with `derive:` configured and the flag\n // absent, every file read is an input to one derivation after the loop,\n // and its managed fields are then compared with what the sources say.\n // Stdin is never an input — there is no history behind it.\n const deriveConfig = config?.derive;\n // A `derive:` with no `fields` manages the merge-safe fields, each only on\n // a page whose schemas claim it (0069), so each page's own set is known\n // once its schemas are resolved. `fields: []` manages nothing.\n const configuredFields = managedFields(deriveConfig);\n const defaultedFields = deriveConfig !== undefined && deriveConfig.fields === undefined;\n const deriveWillRun =\n deriveConfig !== undefined &&\n configuredFields.length > 0 &&\n opts.derive !== false;\n /** Under the merge-safe default, the fields each page's schemas claim. */\n const pageManaged = new Map<string, readonly string[]>();\n // A corpus check naming the `derived` or `resolved` table needs the same\n // inputs, content included (the git source hashes it to spot an uncommitted\n // body), so the one list serves both — and fills only when something will\n // read it. Both names count: a check reading `resolved` alone in a repo\n // with no managed fields would otherwise keep no inputs, derive nothing,\n // and read every column NULL without saying so.\n const derivedChecks = checksWillRun\n ? configuredChecks.filter((c) => mentionsDerived(c.query) || mentionsResolved(c.query))\n : [];\n const checksNeedDerived = derivedChecks.length > 0;\n const deriveInputs: DeriveInput[] = [];\n // Each compared file's encryption view (0045), so a marked managed field is\n // compared by its plaintext and never named in the clear.\n const managedViews = new Map<string, ManagedView>();\n const keepDeriveInputs = deriveWillRun || checksNeedDerived;\n // One derivation for the run, over the union of what either reader needs:\n // the managed fields the comparison judges, and the columns the checks\n // can read. Memoized so a check that names the table and a managed field\n // share the git walk (and the gh or glab round-trip) rather than each paying\n // for one. A source that cannot answer is the run's error either way — a\n // half-derived comparison would read as \"all current\", the false green\n // the channel refuses — and the hint names the reader that asked.\n // The configured commands (0042) are part of both: a command's field is\n // managed like a built-in one, and is a column the checks can read.\n const deriveCommands = commandsOf(deriveConfig);\n // Under the default, each page adds the fields it claims as it is read.\n const deriveFields = new Set<string>(deriveWillRun && !defaultedFields ? configuredFields : []);\n const readable = derivableFields(deriveCommands);\n for (const c of derivedChecks) for (const f of fieldsForSql(c.query, readable)) deriveFields.add(f);\n // The manifests that hold a page's `provenance` record (0046), for evidence rule 2.\n const provenanceManifests =\n keepDeriveInputs &&\n (deriveFields.has(PROVENANCE_FIELD) || (deriveWillRun && configuredFields.includes(PROVENANCE_FIELD)))\n ? readerManifests(declaredCollections, configDir ?? cwd, base)\n : [];\n const derivedOnce = once(async (): Promise<DeriveResult> => {\n const derived = await deriveMetadata(deriveInputs, {\n cwd,\n base,\n ...(configDir !== undefined ? { configDir } : {}),\n sources: deriveConfig?.sources ?? [...DERIVE_SOURCES],\n fields: [...deriveFields],\n ...(deriveConfig?.codeowners !== undefined\n ? { codeowners: deriveConfig.codeowners }\n : {}),\n ...(deriveCommands !== undefined ? { commands: deriveCommands } : {}),\n cache: opts.cache ?? true,\n now: opts.now ?? (() => new Date()),\n machines: machinesOf(deriveConfig),\n });\n assertSourcesAvailable(\n derived.sources,\n deriveWillRun\n ? \"pass --no-derive to skip the comparison, or narrow derive.sources\"\n : \"narrow derive.sources in manni.config.yaml\",\n );\n // A source that answered, with a caveat worth one line: a repository\n // with no CODEOWNERS file derives null owners rather than failing.\n for (const [name, status] of Object.entries(derived.sources)) {\n if (status.available && status.reason !== undefined) {\n opts.onNotice?.(`${name}: ${status.reason}`);\n }\n }\n return derived;\n });\n\n const processOne = async (\n label: string,\n content: string,\n extension: string,\n ): Promise<void> => {\n const extractor =\n forcedExtractor ?? extractorForExtension(extension);\n if (!extractor) {\n throw new DocmetaError(\n `Unsupported file type \"${extension}\" for \"${label}\". Supported: ${supportedExtensions().join(\", \")}. Use --as to override.`,\n );\n }\n\n const members = membersFor(label);\n let extracted;\n try {\n extracted = extractor.extract(content, label, {\n elements: resolveElements(label, config, members),\n });\n } catch (err) {\n // A `DocmetaError` out of an extractor is operational, not a bad\n // document — it aborts the run rather than counting as a file failure.\n if (err instanceof DocmetaError) throw err;\n // A page that does not parse names no `$schema`, so `skipDefaultOnly`\n // judges it by what the config alone would apply to it.\n if (opts.skipDefaultOnly === true && defaultOnly(label, members)) {\n skippedDefaultOnly.add(label);\n return;\n }\n results.push(\n parseErrorResult(label, extractor.name, errorMessage(err), \"parse\"),\n );\n return;\n }\n // The external-metadata merge sits between extraction and everything downstream,\n // so schema resolution, validation, and the corpus checks all see the one\n // object the document and its manifest entry make together.\n // `merged.extracted` keeps the document's own `lineFor`/`colFor`: a\n // manifest key is not in the document, so those answer `undefined` for it\n // and `merged.locate` answers instead. Rebound rather than shadowed, so\n // every read below — resolution, validation, the collision loop — sees\n // the one merged object.\n //\n // The derive sources take the document's OWN extraction, from before the\n // merge, so `lineFor` answers for its own lines. The comparison itself\n // reads the merged view below: a managed key a local manifest owns\n // (0047) is asserted by the manifest, and `merged.locate` points its\n // finding at the manifest's line. `provenance`'s record may live in a\n // manifest too (0046), which the git source then reads at each commit.\n // A manifest with no keys (proposal 0068) owns what this page's schemas\n // mark external, so those marks are read before the merge.\n const merged = await mergeWithMarks(label, extracted, externalMetadata, members, base, {\n encryptionKey,\n marks,\n });\n // A file outside `derive.collections` is derived only when a check\n // reads the derived table (proposal 0070).\n if (\n keepDeriveInputs &&\n label !== STDIN_LABEL &&\n (checksNeedDerived || deriveCovers(deriveConfig, members))\n ) {\n const place = provenanceManifests.length === 0\n ? undefined\n : readerPlace(label, extracted.data, provenanceManifests, declaredCollections, configDir ?? cwd, base, merged.marked);\n // Rule 1 of 0069: the manifest that owns a dated field is read at each fact commit.\n const owned =\n declaredCollections.length === 0\n ? {}\n : stampManifests(label, extracted.data, declaredCollections, configDir ?? cwd, base, merged.marked, STAMPED_DATE_FIELDS);\n deriveInputs.push({\n label,\n absPath: resolve(base, label),\n content,\n extracted,\n ...(place !== undefined ? { provenanceManifest: place } : {}),\n ...(Object.keys(owned).length > 0 ? { stampManifests: owned } : {}),\n });\n }\n // The page's own keys, for telling a value the page holds from one a\n // manifest supplied (proposal 0047).\n const own = extracted.data;\n extracted = merged.extracted;\n // The merged data before any schema is known, so a document whose schema\n // set fails still asserts what its manifest supplies. No refs means no\n // marks, which is exactly what the encryption view below would find.\n // Replaced by that view once it is built.\n if (deriveWillRun && label !== STDIN_LABEL) {\n managedViews.set(label, {\n data: extracted.data,\n marked: [],\n hidden: [],\n refs: [],\n locate: merged.locate,\n });\n }\n for (const j of merged.joins) {\n const byValue =\n joinHits.get(j.field) ??\n new Map<string, { label: string; line?: number; file: string; shown: string }[]>();\n const line = extracted.lineFor(j.field);\n const hits = byValue.get(j.value) ?? [];\n // A finding names the join value as the page holds it: the ciphertext\n // of an encrypted field, never its plaintext.\n hits.push({\n label,\n file: j.file,\n shown: j.pageValue ?? j.value,\n ...(line != null ? { line } : {}),\n });\n byValue.set(j.value, hits);\n joinHits.set(j.field, byValue);\n }\n if (checksWillRun) checkEntries.push({ label, extracted });\n\n let resolved: ResolvedSchemaSet;\n try {\n resolved = resolveSchemaSetWithSource({\n filePath: label,\n fileSchema: extracted.data[FILE_SCHEMA_KEY],\n cliSchemas: opts.cliSchemas,\n config,\n memberOf: members,\n // A document's own `$schema` is measured from the run's directory, the\n // same base `loadSchema` will read it from, and contained to the\n // repository the run is standing in.\n fileBase: cwd,\n trustRoot,\n onNotice: opts.onNotice,\n });\n } catch (err) {\n results.push(\n parseErrorResult(label, extractor.name, errorMessage(err), \"schema\"),\n );\n return;\n }\n\n if (opts.skipDefaultOnly === true && resolved.source === \"default\") {\n skippedDefaultOnly.add(label);\n return;\n }\n const schemaSet = resolved.schemas;\n // The merge-safe default (0069): this page manages what its schemas claim.\n // A set that fails to load claims nothing, and validation says why.\n if (\n deriveWillRun &&\n defaultedFields &&\n label !== STDIN_LABEL &&\n deriveCovers(deriveConfig, members)\n ) {\n let claimed: ReadonlySet<string> = new Set();\n try {\n claimed = await validator.claimedProperties(schemaSet);\n } catch (err) {\n if (!(err instanceof DocmetaError)) throw err;\n }\n const own = configuredFields.filter((f) => claimed.has(f));\n pageManaged.set(label, own);\n for (const f of own) deriveFields.add(f);\n }\n let errors: FieldError[];\n try {\n // Proposal 0045: marked values are validated as their plaintext, on a\n // copy; the page's own object is never mutated, and no finding may say\n // more about an encrypted value than the page did.\n const view = await encryptionView({\n data: extracted.data,\n refs: schemaSet,\n validator,\n key: encryptionKey,\n locate: merged.locate,\n });\n unverified += view.unverified.length;\n if (deriveWillRun && label !== STDIN_LABEL) {\n managedViews.set(label, {\n data: view.data,\n marked: view.marked,\n hidden: [...view.unreadable, ...view.unverified],\n refs: schemaSet,\n locate: merged.locate,\n });\n }\n errors = [\n ...settleFindings(\n await validator.validate(\n view.data,\n schemaSet,\n extracted.lineFor,\n extracted.colFor,\n merged.locate,\n ),\n view,\n extracted,\n merged.locate,\n ),\n ...encryptionFindings(view, extracted, merged.locate),\n // Over the decrypted view, the object validation evaluated: a mark\n // counts where Ajv takes a branch, and a branch may read a value.\n ...(await locationFindings(label, own, view.data, schemaSet, members, merged, extracted.lineFor)),\n ];\n } catch (err) {\n // A schema the *document* chose failing to load — unparseable, missing,\n // integrity mismatch — is that document's failure, and is filed as one.\n // Letting it escape meant a single contributed file naming any non-JSON\n // path in the repo aborted the whole run: exit 2, and nothing reported\n // about any file, including the ones that were fine.\n //\n // Every other source stays operational on purpose. A schema the operator\n // configured is not one document's problem; it invalidates the run, and\n // reporting it per-file would repeat the same error once per document\n // while implying the documents were at fault.\n if (!(err instanceof DocmetaError) || resolved.source !== \"document\") {\n throw err;\n }\n results.push(\n parseErrorResult(label, extractor.name, err.message, \"schema\"),\n );\n return;\n }\n // A document carrying a key a manifest owns (0020 across files: neither\n // channel wins, and the discarded value would be exactly the one nobody\n // checked). Filed against the document at the key's own line.\n for (const { key, file, collection } of merged.collisions) {\n const line = extracted.lineFor(key);\n errors.push({\n schema: EXTERNAL_OWNED_SCHEMA,\n keyword: EXTERNAL_KEYWORD,\n subject: key,\n instancePath: externalMetadataPointer(key),\n message: `\"${key}\" is owned by manifest ${file} (collection ${collection}); remove it from the document`,\n ...(line != null ? { line } : {}),\n });\n }\n results.push({\n file: label,\n format: extractor.name,\n ok: !errors.some(isErrorSeverity),\n schemas: schemaSet,\n errors,\n });\n };\n\n if (usingStdin) {\n const content = opts.stdinContent ?? \"\";\n if (!forcedExtractor) {\n throw new DocmetaError(\n STDIN_REQUIRES_AS,\n );\n }\n await processOne(STDIN_LABEL, content, forcedExtractor.extensions[0] ?? \"\");\n }\n\n for (const file of files) {\n const content = await readFile(resolve(base, file), \"utf8\");\n await processOne(file, content, extname(file));\n }\n\n // Once per run, however many files held them (proposal 0045): the exit code\n // is unaffected, and the count is of values, not of the findings dropped.\n if (unverified > 0) opts.onNotice?.(unverifiedWarning(unverified));\n\n // Two documents carrying one join value (0039): one entry matched both,\n // and the manifest cannot tell them apart. A finding on each, at the\n // field's own line, whether or not the run is scoped — it is about the\n // documents loaded, not the corpus. Then, on a corpus run, a field entry\n // nothing matched is the same orphan a path entry is.\n if (externalMetadata) {\n const byLabel = new Map(results.map((r) => [r.file, r]));\n const matched = new Map<string, Set<string>>();\n for (const [field, byValue] of joinHits) {\n matched.set(field, new Set(byValue.keys()));\n for (const hits of byValue.values()) {\n if (hits.length < 2) continue;\n for (const hit of hits) {\n const others = hits\n .filter((h) => h.label !== hit.label)\n .map((h) => h.label)\n .join(\", \");\n const result = byLabel.get(hit.label);\n if (!result) continue;\n result.errors.push({\n schema: EXTERNAL_DUPLICATE_SCHEMA,\n keyword: EXTERNAL_KEYWORD,\n subject: hit.shown,\n instancePath: externalMetadataPointer(field),\n message: `${hits.length} documents carry ${field} \"${hit.shown}\"; ${hit.file} cannot tell them apart (${others})`,\n ...(hit.line != null ? { line: hit.line } : {}),\n });\n result.ok = false;\n }\n }\n }\n // Same corpus invariant as the path-entry orphans above, and the same\n // reading of `--collection`: a named collection is a corpus of its own.\n if (!scopedByFlags) {\n const covered = scopedToCollections ? collections.map((c) => c.name) : undefined;\n const orphans = orphanJoins(externalMetadata, matched, covered);\n if (orphans.length > 0) throw orphanError(orphans);\n }\n }\n\n // Corpus checks (0026), after the per-file loop and before the baseline so\n // their findings ride the same ratchet the schemas get. The disqualifying\n // conditions live with `scoped`, computed before the loop above.\n if (configuredChecks.length > 0 && opts.checks !== false) {\n if (scoped) {\n // Name the reason when it is `--collection`: \"scoped\" alone reads as a\n // stray positional path, and the operator who narrowed the run by name\n // is the one most likely to expect the checks to have run.\n opts.onNotice?.(\n scopedToCollections\n ? `corpus checks skipped: run is scoped to collections ${collections\n .map((c) => c.name)\n .join(\", \")}`\n : \"corpus checks skipped: run is scoped\",\n );\n } else {\n const findings = await runChecks(configuredChecks, checkEntries, {\n // Every declared collection is a view (0041 rule 7), holding the\n // members this run loaded — decided by the same path arithmetic\n // `membersFor` uses, so a check and a `manni meta query` over the same\n // corpus see the same collections.\n collections: declaredCollections,\n ...(configDir !== undefined ? { configDir } : {}),\n base,\n // A check that names the `derived` table (0040) gets the same view\n // `query` builds, from the run's one derivation — which already\n // covers every field the checks can read, so the list handed back\n // here is not needed. Built only when asked for, because building\n // it spawns git.\n derive: async () => (await derivedOnce()).records,\n // Its columns include the configured commands' keys (0042), which a\n // check's context cannot read from a config since 0041.\n ...(deriveCommands !== undefined ? { commands: deriveCommands } : {}),\n });\n const byFile = new Map(results.map((r) => [r.file, r]));\n for (const [file, errs] of findings) {\n // Unreachable while runChecks vets every path against the loaded set,\n // which is a subset of `results` by construction — but a missed merge\n // must be a loud failure, not findings silently dropped.\n const result = byFile.get(file);\n if (!result && skippedDefaultOnly.has(file)) continue;\n if (!result) {\n throw new DocmetaError(\n `check findings for \"${file}\" have no validation result to attach to.`,\n );\n }\n result.errors.push(...errs);\n result.ok = result.ok && !errs.some(isErrorSeverity);\n }\n }\n }\n\n // The derived comparison (0040): what each document asserts for its\n // managed fields against what the sources say. Per file, so it runs on\n // scoped runs too, and before the baseline so a stale stamp rides the same\n // ratchet every other finding does. Reads only the configured fields from\n // the run's one derivation, which may hold more for the checks' sake.\n if (deriveWillRun && deriveInputs.length > 0) {\n const derived = await derivedOnce();\n const byFile = new Map(results.map((r) => [r.file, r]));\n for (const input of deriveInputs) {\n const record: DerivedRecord | undefined = derived.records.get(input.label);\n const result = byFile.get(input.label);\n if (!record || !result) continue;\n // Proposal 0045: a marked managed field is compared by its plaintext\n // and named as `(encrypted)`. One no key could read is left\n // uncompared: the run already says so once, and a guess either way\n // would be a false finding or a false green.\n const managed = managedViews.get(input.label);\n // A file outside `derive.collections` is not compared (proposal 0070).\n const managedHere = !deriveCovers(deriveConfig, membersFor(input.label))\n ? []\n : defaultedFields\n ? (pageManaged.get(input.label) ?? [])\n : configuredFields;\n const fields = managedHere.filter(\n (field) => !(managed?.hidden.some((p) => isAtOrUnder(p, pointerOf(field))) ?? false),\n );\n let marked: readonly string[] = [];\n if (managed !== undefined) {\n // Read over the page as `derive` would stamp it: an absent property\n // is one Ajv never evaluates, so an unset field's mark only shows\n // once its value is in place.\n const stamped: Record<string, unknown> = { ...managed.data };\n for (const field of fields) {\n const d = record.fields[field];\n if (d != null) stamped[field] = d.value;\n }\n marked = [...managed.marked, ...(await validator.markedPointers(stamped, managed.refs))];\n }\n const asserted = (field: string): unknown =>\n managed !== undefined ? managed.data[field] : input.extracted.data[field];\n const findings = fields.flatMap((field) => {\n // Proposal 0046: `provenance` is judged range by range, against the\n // record wherever it lives, and each finding lands on its range's line.\n if (field === PROVENANCE_FIELD) {\n const derivation = derived.provenance?.get(input.label);\n if (derivation === undefined) return [];\n return provenanceFindings(\n compareProvenance(provenanceEntries(asserted(field)), derivation),\n derivation.page.bodyLine,\n );\n }\n const compared = compareDerived(field, asserted(field), record.fields[field]);\n const at = pointerOf(field);\n return staleFindings(\n [marked.some((p) => isAtOrUnder(p, at)) ? redactedDerived(compared) : compared],\n input.extracted.lineFor,\n managed?.locate,\n );\n });\n if (findings.length === 0) continue;\n result.errors.push(...findings);\n result.ok = false;\n }\n }\n\n // Fingerprints must not depend on where the command was run from, so a\n // local file schema ref is measured against the config's directory.\n const frame: FingerprintContext = { cwd, base: configDir ?? cwd, runBase: base };\n\n const { results: reported, baseline } = await settleBaseline(\n results,\n resolveBaselineRequest(opts, config?.baseline, configDir, cwd, {\n current: DEFAULT_BASELINE_PATH,\n legacy: LEGACY_BASELINE_PATH,\n }),\n frame,\n );\n\n const failed = reported.filter((r) => !r.ok).length;\n const count = (keep: (e: FieldError) => boolean): number =>\n reported.reduce((n, r) => n + r.errors.filter(keep).length, 0);\n const warnings = count((e) => e.severity === \"warning\");\n const notices = count((e) => e.severity === \"notice\");\n const summary: RunSummary = {\n files: reported.length,\n passed: reported.length - failed,\n failed,\n errors: count(isErrorSeverity),\n // Omitted at zero, like `gitignoreSkipped` below: only the location\n // findings (proposal 0047) are warnings, so a run with no\n // `x-manni-location` marks keeps the summary as it was.\n ...(warnings > 0 ? { warnings } : {}),\n ...(notices > 0 ? { notices } : {}),\n // Omitted when nothing was skipped: there is nothing to audit, and the\n // JSON summary stays as it was for every run in a clean repo.\n ...(gitignoreSkipped > 0 ? { gitignoreSkipped } : {}),\n ...(baseline ? { baseline } : {}),\n };\n\n return { results: reported, summary, frame };\n}\n","/**\n * External metadata (proposal 0037): a private manifest joined to public\n * documents.\n *\n * A manifest is a YAML mapping from document to a mapping of owned keys. Its\n * values are merged into each named document's extracted metadata before\n * schema resolution, so every command sees one object. The manifest itself\n * is never a document: it registers no extractor, appears in no `docs` row,\n * and is what 0031 called a join table rather than the standalone data file\n * it rejected.\n *\n * Three rules decide everything else here:\n *\n * - **Keys are owned.** Each manifest declares the top-level keys it supplies,\n * ownership is disjoint across manifests (asserted by the config parser), and\n * a manifest entry supplying a key it does not own is an operational error.\n * A manifest that declares none (proposal 0068) owns, for each page, what\n * that page's schemas mark `x-manni-location: external`, less what its\n * siblings name. `ownsKey` decides it. A value such a manifest holds for a\n * key the page does not mark is the unowned-key refusal, raised at the\n * merge because ownership is per page. With the page's marks unknown, the\n * manifest owns nothing for it and nothing is judged.\n * Ownership is what gives a write to an absent key somewhere to go, and it\n * is what makes a document carrying a private key visible with or without\n * a manifest entry.\n * - **A document carrying an owned key is a collision, not a tiebreak.** 0020's\n * rule across files: neither channel wins, because the discarded value is\n * exactly the one nobody checked. The caller files the finding; the merge\n * keeps the document's value so the report shows what the public site\n * would publish.\n * - **A manifest names documents by exact path, or by one frontmatter field.**\n * No globs and no cascade (0004 rejected partial merges of config for the\n * reason that a silently merged result changes what the contract means).\n * A path is relative to the config's directory. A field join (0039)\n * matches the extracted value of that field, so a rename cannot orphan an\n * entry; what can is two pages sharing one value, which is a finding on\n * both.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport {\n LineCounter,\n isMap,\n isNode,\n isScalar,\n isSeq,\n parseDocument,\n type Node,\n} from \"yaml\";\nimport {\n externalMetadataOrigin,\n isMember,\n matchesCollectionPaths,\n neverOwned,\n ownsKey,\n type CollectionConfig,\n type ExternalMetadataConfig,\n} from \"../../shared/collections.js\";\nimport {\n PAGE_PLACEHOLDER,\n findPageManifests,\n hasPagePlaceholder,\n pageManifestPath,\n sameFile,\n} from \"../../shared/page-manifest.js\";\nimport { isMissing } from \"../../shared/manifest-cas.js\";\nimport { FILE_SCHEMA_KEY } from \"./resolve-schema.js\";\nimport { classifyRef } from \"./schema-registry.js\";\nimport { ManifestCache } from \"./manifest-cache.js\";\nimport { fetchExternalMetadata } from \"./external-metadata-fetch.js\";\nimport { STDIN_LABEL } from \"./load-files.js\";\nimport { escapePointerSegment, positionForFactory } from \"../extractors/pointer.js\";\nimport { DocmetaError, type ExtractedMetadata } from \"../types.js\";\nimport { decryptValue, isEncryptedValue } from \"../../shared/encryption.js\";\nimport { EncryptionRefusal, META_CONTEXT } from \"./encrypted.js\";\n\n/**\n * The `schema` ref a collision finding carries, and so its baseline and rule\n * identity: `external:owned/external`. Shaped like `check:<name>` so\n * `classifyRef` passes it through as a built-in id rather than resolving it\n * as a cwd-relative file path, and reserved in the registry for the same\n * reason `check` is.\n */\nexport const EXTERNAL_OWNED_SCHEMA = \"external:owned\";\n\n/**\n * The `schema` ref of a duplicate-join finding (0039): two documents carry\n * the same value of a join field, so one manifest entry matched both.\n */\nexport const EXTERNAL_DUPLICATE_SCHEMA = \"external:duplicate\";\n\n/**\n * The `keyword` every external-metadata finding carries: no Ajv keyword\n * produced it.\n */\nexport const EXTERNAL_KEYWORD = \"external\";\n\n/** The join that names documents by path, and the default. */\nexport const PATH_JOIN = \"path\";\n\n/** One value a manifest supplied, and where it was written. */\nexport interface ExternalMetadataValue {\n value: unknown;\n /** The collection whose manifest supplied it (proposal 0041). */\n collection: string;\n /** Manifest path as the run reports it: relative to the run's base, posix — or the URL. */\n file: string;\n /** 1-based line of the key in the manifest, when known. */\n line?: number;\n /**\n * 1-based manifest line of every node inside `value`, keyed by the JSON\n * Pointer relative to `value` (`/2/source/file`). A mapping member sits on\n * its key's line, and a list item on the line its node starts. Present only\n * when `value` is a mapping or a list with members; `line` answers for the\n * value itself.\n */\n lines?: ReadonlyMap<string, number>;\n}\n\n/** One manifest entry, for the orphan checks. */\nexport interface ExternalMetadataEntry {\n /** The collection whose manifest declared it (proposal 0041). */\n collection: string;\n /** `path`, or the frontmatter field this entry is keyed by. */\n join: string;\n /** Absolute document path, for a path entry. */\n abs?: string;\n /** The key exactly as written in the manifest. */\n spelled: string;\n /** Manifest path as the run reports it. */\n file: string;\n /** 1-based line of the entry in the manifest, when known. */\n line?: number;\n}\n\ntype Values = Map<string, ExternalMetadataValue>;\n\n/**\n * The same mapping as `Values`, as a cached parse hands it out. A caller that\n * holds one may read it and may copy it, and cannot write into the parse the\n * next command will be given.\n */\ntype ReadonlyValues = ReadonlyMap<string, ExternalMetadataValue>;\n\n/**\n * One manifest's parse, on its own: the values it supplies, indexed the way\n * its join indexes them, and the entries it declares. Isolated rather than\n * merged in place, because the same result is handed to the next command that\n * reads the same file.\n *\n * Readonly to the bottom of the maps, not just at the top. An outer\n * `ReadonlyMap` of mutable inner ones stops an add and a remove on the key set\n * and stops nothing else: anything holding an inner map could `set` a value\n * straight into the parse the next command is given. The copy-in below is\n * careful today, and the type is what keeps the change after it careful.\n */\ninterface ParsedManifest {\n readonly values: ReadonlyMap<string, ReadonlyValues>;\n readonly entries: readonly ExternalMetadataEntry[];\n}\n\n/**\n * Every manifest this process has parsed, by path, `mtimeMs` and size. A\n * manifest is data a whole run is judged against, so a stale parse would be a\n * wrong verdict rather than a slow one; `manifest-cache.ts` says what keeps it\n * fresh, and why a stat alone is not enough.\n */\nconst parsedManifests = new ManifestCache<ParsedManifest>();\n\n/**\n * A manifest with no `keys` (proposal 0068), as one index loaded it. What it\n * owns is decided per page, from the page's marks, so it is kept apart from\n * `owners`, which holds what the config alone decides.\n */\ninterface ImpliedOwner {\n /** The whole declared collection, for `ownsKey`. */\n collection: CollectionConfig;\n manifest: ExternalMetadataConfig;\n /** The manifest as a collision names it: its reported path, its URL, or its `{page}` pattern. */\n file: string;\n /** Every file its values carry, as the run reports them: one, or one per page. */\n files: Set<string>;\n}\n\n/**\n * The keyless manifests each index was loaded with. Kept beside the index, as\n * `perPageRules` is, so `ExternalMetadataIndex` keeps its shape.\n */\nconst impliedOwners = new WeakMap<ExternalMetadataIndex, readonly ImpliedOwner[]>();\n\n/** One `{page}` entry of a loaded index: what a stray walk needs to find its files. */\ninterface PerPageRule {\n collection: CollectionConfig;\n manifest: ExternalMetadataConfig;\n configDir: string;\n}\n\n/**\n * The `{page}` entries each index was loaded with (proposal 0058). Kept beside\n * the index rather than on it, so `ExternalMetadataIndex` keeps the shape\n * every caller already builds and reads, and `orphanEntries` keeps its\n * signature while it learns to report a stray file.\n */\nconst perPageRules = new WeakMap<ExternalMetadataIndex, readonly PerPageRule[]>();\n\n/**\n * The orphans `orphanEntries` found as stray files rather than as entries in\n * a file a run read, so `orphanError` tells the author to remove the file.\n */\nconst strayEntries = new WeakSet<ExternalMetadataEntry>();\n\n/** Every manifest of a run, loaded once and consulted per document. */\nexport interface ExternalMetadataIndex {\n /**\n * Owned key -> every collection that owns it, with the manifest that does.\n *\n * A list rather than one entry, because two collections may legitimately\n * each own the same key (0041 rule 5): `guides` and `blog` can both supply\n * `owner`. Ambiguity only exists for a file that is a member of both, which\n * is decided per file in `mergeExternalMetadata`.\n */\n owners: ReadonlyMap<string, readonly { collection: string; file: string }[]>;\n /** Path-joined manifests: absolute document path -> owned key -> value. */\n byPath: ReadonlyMap<string, ReadonlyMap<string, ExternalMetadataValue>>;\n /** Field-joined manifests: field -> value -> owned key -> value. */\n byField: ReadonlyMap<string, ReadonlyMap<string, ReadonlyMap<string, ExternalMetadataValue>>>;\n /** Every manifest entry, in manifest order. */\n entries: readonly ExternalMetadataEntry[];\n}\n\nexport interface LoadExternalMetadataOptions {\n /** Directory `externalMetadata[].file` and every manifest key resolve from. */\n configDir: string;\n /** Directory the run's file labels are relative to; manifests are reported the same way. */\n base: string;\n /** `--offline` / `offline:`: a URL manifest is refused rather than fetched (0038). */\n offline?: boolean;\n /** Network timeout for a URL manifest; the schema fetch's default otherwise. */\n timeoutMs?: number;\n /** For tests: the environment `tokenEnv` is read from. */\n env?: Record<string, string | undefined>;\n /**\n * The run's documents, as absolute paths (proposal 0058). An entry whose\n * `file` holds `{page}` names one manifest per page, so it is read for\n * exactly these pages, each that belongs to its collection, and for nothing\n * else. Absent, such an entry reads no file. An entry without the\n * placeholder ignores this and loads its one manifest as it always has.\n */\n pages?: readonly string[];\n}\n\n/** A place a merged value lives, for a finding that must name it. */\nexport interface SourceLocation {\n file: string;\n line?: number;\n col?: number;\n}\n\n/** A key the document carries that a manifest owns. */\nexport interface ExternalMetadataCollision {\n key: string;\n /** The owning manifest, as the run reports it. */\n file: string;\n /** The collection that manifest belongs to (proposal 0041). */\n collection: string;\n}\n\n/** A field-joined entry a document matched (0039). */\nexport interface ExternalMetadataJoin {\n field: string;\n /** The value matched: the field's plaintext, decrypted first when the page holds it encrypted. */\n value: string;\n /**\n * The field as the page holds it, when that differs from `value`: the\n * ciphertext of an encrypted join field (proposal 0045). A finding about\n * the join names this, never the plaintext.\n */\n pageValue?: string;\n /** The manifest, as the run reports it. */\n file: string;\n /** The collection that manifest belongs to (proposal 0041). */\n collection: string;\n}\n\n/** What `mergeExternalMetadata` hands back. */\nexport interface MergedMetadata {\n /** The document's metadata with every owned key the manifest supplied. */\n extracted: ExtractedMetadata;\n /**\n * Owned keys the document itself also carried, in document order, each\n * with the manifest that owns it — so the finding names it without a\n * second lookup, and without a fallback for an index that is not there.\n */\n collisions: ExternalMetadataCollision[];\n /** Field-joined entries this document matched, one per manifest at most. */\n joins: ExternalMetadataJoin[];\n /**\n * Where a merged pointer's value lives. Answers only for a value the\n * manifest supplied — a bare key or its `/key` pointer, and anything\n * beneath it — and `undefined` for everything the document owns, which is\n * what `lineFor` is for.\n *\n * The line is the deepest manifest node the pointer reaches, so\n * `/citations/2` is the third item's line and `/citations/2/source/file`\n * that member's. A pointer past what the manifest holds falls back to the\n * nearest ancestor that exists, and at worst to the owned key's line.\n */\n locate: (pointer: string) => SourceLocation | undefined;\n}\n\nconst posix = (p: string): string => p.split(sep).join(\"/\");\n\n/** How a run spells a manifest: relative to its base, like every file label. */\nexport function reportedPath(abs: string, base: string): string {\n const rel = relative(base, abs);\n return rel === \"\" ? \".\" : posix(rel);\n}\n\n/**\n * One value or entry of a cached parse, spelled the way this run reports its\n * manifest. Answers the original when the spelling already matches, which is\n * every run that parsed the manifest itself.\n */\nfunction reported<T extends { file: string }>(of: T, file: string): T {\n return of.file === file ? of : { ...of, file };\n}\n\n/** The join an external-metadata config asks for: `path` unless it names a field. */\nexport function externalMetadataJoin(\n manifest: Pick<ExternalMetadataConfig, \"join\">,\n): string {\n return manifest.join ?? PATH_JOIN;\n}\n\n/**\n * Load every manifest of every collection the run covers. Resolves to `null`\n * when none of them declares one, which is every setup that existed before\n * this feature.\n *\n * Every refusal is a `DocmetaError`: the manifest is a config-supplied input,\n * and one that is missing or misshapen is the run's problem, not a\n * document's (0014).\n */\nexport async function loadExternalMetadata(\n collections: readonly CollectionConfig[],\n opts: LoadExternalMetadataOptions,\n): Promise<ExternalMetadataIndex | null> {\n const configured = collections.flatMap((c) =>\n c.externalMetadata.map((m) => ({ collection: c.name, manifest: m })),\n );\n if (configured.length === 0) return null;\n\n const owners = new Map<string, { collection: string; file: string }[]>();\n const byPath = new Map<string, Values>();\n const byField = new Map<string, Map<string, Values>>();\n const entries: ExternalMetadataEntry[] = [];\n /** Every `{page}` manifest resolved so far, and the page that resolved it. */\n const resolvedBy = new Map<string, string>();\n const rules: PerPageRule[] = [];\n const implied: ImpliedOwner[] = [];\n\n for (const { collection, manifest } of configured) {\n // The whole collection, because a `{page}` entry is read per member page.\n const declared = collections.find(\n (c) => c.name === collection && c.externalMetadata.includes(manifest),\n );\n if (\n declared !== undefined &&\n classifyRef(manifest.file).kind !== \"url\" &&\n hasPagePlaceholder(manifest.file)\n ) {\n const owner = await loadPerPage(declared, manifest, opts, resolvedBy, { owners, byPath, byField, entries });\n if (owner !== undefined) implied.push(owner);\n rules.push({ collection: declared, manifest, configDir: opts.configDir });\n continue;\n }\n // A URL manifest (0038) is reported as the URL itself, and fetched every\n // run: it is data, and a stale copy would validate against the wrong\n // values. A path is reported relative to the run's base, like every\n // file label. Either way the manifest's *keys* resolve from the config\n // directory, so a remote manifest names documents the same way a local\n // one does.\n const join = externalMetadataJoin(manifest);\n let parsed: ParsedManifest;\n let file: string;\n if (classifyRef(manifest.file).kind === \"url\") {\n file = manifest.file;\n const text = await fetchExternalMetadata(manifest.file, {\n ...(manifest.tokenEnv !== undefined ? { tokenEnv: manifest.tokenEnv } : {}),\n ...(opts.offline !== undefined ? { offline: opts.offline } : {}),\n ...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),\n ...(opts.env !== undefined ? { env: opts.env } : {}),\n });\n parsed = parseManifest(manifest, collection, text, file, opts.configDir, join, ownership(declared, manifest));\n } else {\n const abs = isAbsolute(manifest.file)\n ? manifest.file\n : resolve(opts.configDir, manifest.file);\n const label = reportedPath(abs, opts.base);\n file = label;\n // One parse per file, per declaration. A manifest unchanged since\n // another command in this process read it is not read again; a written\n // one was dropped by `writeFileAtomic`, and one edited from outside by\n // its `mtimeMs` and size.\n parsed = await parsedManifests.parse(\n abs,\n // `label` is deliberately not part of this. It is the manifest as this\n // run reports it, which is a function of the run's base rather than of\n // the bytes, so two runs over one corpus from two directories parse\n // identically and differ only in a string each value carries. Keying\n // on it would miss the cache for exactly the runs that share a\n // process, which is what a test suite is. The copy-in below writes\n // this run's spelling onto every value and entry instead.\n JSON.stringify([\n collection,\n join,\n opts.configDir,\n variantOf(declared, manifest),\n ]),\n async () =>\n parseManifest(\n manifest,\n collection,\n await readManifest(abs, label),\n label,\n opts.configDir,\n join,\n ownership(declared, manifest),\n ),\n );\n }\n if (manifest.keys === undefined && declared !== undefined) {\n implied.push({ collection: declared, manifest, file, files: new Set([file]) });\n }\n for (const key of manifest.keys ?? []) {\n const list = owners.get(key);\n if (list) list.push({ collection, file });\n else owners.set(key, [{ collection, file }]);\n }\n let target: Map<string, Values>;\n if (join === PATH_JOIN) {\n target = byPath;\n } else {\n const existing = byField.get(join);\n if (existing) target = existing;\n else {\n target = new Map<string, Values>();\n byField.set(join, target);\n }\n }\n // Copied in rather than handed over. The parse is shared with whatever\n // command reads this manifest next, so nothing downstream may hold a\n // reference into it.\n //\n // The copy is also where `file` is set, because the parse may have been\n // made by a run with another base and carries that run's spelling. The\n // walk happens either way, so rewriting costs one object per value.\n for (const [indexKey, values] of parsed.values) {\n const into = target.get(indexKey) ?? new Map<string, ExternalMetadataValue>();\n for (const [key, value] of values) into.set(key, reported(value, file));\n target.set(indexKey, into);\n }\n for (const entry of parsed.entries) entries.push(reported(entry, file));\n }\n const index: ExternalMetadataIndex = { owners, byPath, byField, entries };\n if (rules.length > 0) perPageRules.set(index, rules);\n if (implied.length > 0) impliedOwners.set(index, implied);\n return index;\n}\n\n/**\n * Which keys a manifest's entries may set, as the parse checks it. A manifest\n * with `keys` may set those. A keyless one (proposal 0068) may set any key\n * but the ones it can never own, because which of the rest it owns depends\n * on the page, and is settled at the merge.\n */\ninterface Ownership {\n may: (key: string) => boolean;\n /** Why an entry may not set `key`, as the tail of the refusal. */\n why: (key: string) => string;\n}\n\nfunction ownership(\n declared: CollectionConfig | undefined,\n manifest: ExternalMetadataConfig,\n): Ownership {\n if (manifest.keys !== undefined) {\n const owned = new Set(manifest.keys);\n return {\n may: (key) => owned.has(key),\n why: () => `which this manifest does not own. Add it to the manifest's \"keys\", or remove it from the entry.`,\n };\n }\n const never = neverOwned(declared ?? { externalMetadata: [manifest] }, manifest);\n return {\n may: (key) => !never.has(key),\n why: (key) =>\n key === manifest.join\n ? \"the field this manifest joins on, which the page carries. Remove it from the entry.\"\n : `which another manifest of this collection names in its \"keys\". Move it to that manifest, or remove it from the entry.`,\n };\n}\n\n/** What a parse depends on besides the bytes: the keys, or what a keyless manifest may never own. */\nfunction variantOf(\n declared: CollectionConfig | undefined,\n manifest: ExternalMetadataConfig,\n): unknown {\n // The keys are sorted because they reach the variant as an array, and two\n // declarations that own the same keys in a different order parse to the\n // same thing.\n if (manifest.keys !== undefined) return [...manifest.keys].sort();\n return { never: [...neverOwned(declared ?? { externalMetadata: [manifest] }, manifest)].sort() };\n}\n\n/** The index `loadExternalMetadata` is building, for a helper that adds to it. */\ninterface IndexUnderConstruction {\n owners: Map<string, { collection: string; file: string }[]>;\n byPath: Map<string, Values>;\n byField: Map<string, Map<string, Values>>;\n entries: ExternalMetadataEntry[];\n}\n\n/**\n * One `{page}` entry (proposal 0058): a rule rather than a file, so each of\n * the run's pages that belongs to the collection resolves its own manifest,\n * which is read, checked to be that page's, and indexed. A manifest that does\n * not exist is a page with nothing kept there, and reads as empty.\n *\n * Ownership is still the config's fact, so the entry owns its keys whether or\n * not any page resolved a file. The owner is recorded as the pattern as\n * written, because there is no one file to name.\n */\nasync function loadPerPage(\n declared: CollectionConfig,\n manifest: ExternalMetadataConfig,\n opts: LoadExternalMetadataOptions,\n resolvedBy: Map<string, string>,\n into: IndexUnderConstruction,\n): Promise<ImpliedOwner | undefined> {\n const collection = declared.name;\n const join = externalMetadataJoin(manifest);\n const implied: ImpliedOwner | undefined =\n manifest.keys === undefined\n ? { collection: declared, manifest, file: manifest.file, files: new Set() }\n : undefined;\n for (const key of manifest.keys ?? []) {\n const list = into.owners.get(key);\n if (list) list.push({ collection, file: manifest.file });\n else into.owners.set(key, [{ collection, file: manifest.file }]);\n }\n const target = indexFor(join, into);\n\n for (const pageAbs of opts.pages ?? []) {\n const resolved = pageManifestPath(manifest.file, opts.configDir, pageAbs);\n if (\"outside\" in resolved) {\n // A page above the config directory is a member of nothing, so it is\n // refused only when the collection's own paths claim it: the one case\n // where the placeholder was asked to resolve it and cannot.\n if (resolved.pageRel.startsWith(\"../\") && matchesCollectionPaths(declared, resolved.pageRel)) {\n throw new DocmetaError(outsideRefusal(manifest, collection, resolved.pageRel));\n }\n continue;\n }\n const rel = posix(relative(opts.configDir, pageAbs));\n if (!isMember(declared, rel)) continue;\n\n const earlier = resolvedBy.get(resolved.abs);\n if (earlier !== undefined && earlier !== pageAbs) {\n const [a, b] = [reportedPath(earlier, opts.base), reportedPath(pageAbs, opts.base)].sort();\n throw new DocmetaError(\n `${a ?? \"\"} and ${b ?? \"\"} both resolve ${PAGE_PLACEHOLDER} to ${reportedPath(resolved.abs, opts.base)}. A ${PAGE_PLACEHOLDER} manifest names one page, so rename one of them.`,\n );\n }\n resolvedBy.set(resolved.abs, pageAbs);\n\n const label = reportedPath(resolved.abs, opts.base);\n // The same cache, and the same variant, a concrete manifest parses under.\n // A missing file is never cached, because it cannot be stat'ed.\n const parsed = await parsedManifests.parse(\n resolved.abs,\n JSON.stringify([collection, join, opts.configDir, variantOf(declared, manifest)]),\n async () =>\n parseManifest(\n manifest,\n collection,\n await readPageManifest(resolved.abs, label),\n label,\n opts.configDir,\n join,\n ownership(declared, manifest),\n ),\n );\n implied?.files.add(label);\n\n // Every entry must be this page's own. Compared as files rather than as\n // text (0058 stress test 8): a spelling that differs only in case is one\n // page on a case-insensitive filesystem and two elsewhere, which is the\n // platform's call and not a string's.\n const pageLabel = reportedPath(pageAbs, opts.base);\n for (const entry of parsed.entries) {\n if (entry.abs === undefined || sameFile(entry.abs, pageAbs)) continue;\n const at = entry.line === undefined ? label : `${label}:${String(entry.line)}`;\n throw new DocmetaError(\n `Manifest ${at} names \"${entry.spelled}\", but ${PAGE_PLACEHOLDER} resolved this file for \"${pageLabel}\". A per-page manifest holds one entry, for its own page.`,\n );\n }\n\n // Indexed under the page's own path, which the check above proved every\n // path entry names, so a lookup by the run's spelling of the page finds it.\n for (const [indexKey, values] of parsed.values) {\n const key = join === PATH_JOIN ? pageAbs : indexKey;\n const merged = target.get(key) ?? new Map<string, ExternalMetadataValue>();\n for (const [owned, value] of values) merged.set(owned, reported(value, label));\n target.set(key, merged);\n }\n for (const entry of parsed.entries) {\n into.entries.push({\n ...reported(entry, label),\n ...(entry.abs === undefined ? {} : { abs: pageAbs }),\n });\n }\n }\n return implied;\n}\n\n/** The index a manifest with this join is merged into. */\nfunction indexFor(join: string, into: IndexUnderConstruction): Map<string, Values> {\n if (join === PATH_JOIN) return into.byPath;\n const existing = into.byField.get(join);\n if (existing) return existing;\n const created = new Map<string, Values>();\n into.byField.set(join, created);\n return created;\n}\n\n/**\n * The refusal for a page a `{page}` entry would resolve above the config\n * directory. Exported for the writers that resolve a page's manifest\n * themselves (`relocate`, `fill`, `derive`, `query`).\n */\nexport function outsideRefusal(\n manifest: ExternalMetadataConfig,\n collection: string,\n pageRel: string,\n): string {\n const tail = `for \"${pageRel}\". A ${PAGE_PLACEHOLDER} manifest stays under the config file.`;\n const origin = externalMetadataOrigin(manifest);\n if (origin === undefined) {\n return `externalMetadata file \"${manifest.file}\" of collection ${collection} resolves outside the config file's directory ${tail}`;\n }\n return `${origin.source}: ${origin.where}.file resolves outside ${origin.source}'s directory ${tail}`;\n}\n\n/**\n * A `{page}` manifest's text (0058 § 2): one that does not exist is a page\n * with nothing kept there, and reads as empty. Every other failure keeps\n * `readManifest`'s refusal, so a permission error is still reported.\n */\nasync function readPageManifest(abs: string, file: string): Promise<string> {\n try {\n return await readFile(abs, \"utf8\");\n } catch (err) {\n if (isMissing(err)) return \"\";\n throw unreadable(file, err);\n }\n}\n\nasync function readManifest(abs: string, file: string): Promise<string> {\n try {\n return await readFile(abs, \"utf8\");\n } catch (err) {\n throw unreadable(file, err);\n }\n}\n\n/** The refusal every manifest shares when it cannot be read. */\nfunction unreadable(file: string, err: unknown): DocmetaError {\n const reason = err instanceof Error ? err.message : String(err);\n return new DocmetaError(`Manifest ${file} could not be read: ${reason}`);\n}\n\n\nfunction parseManifest(\n manifest: ExternalMetadataConfig,\n collection: string,\n text: string,\n file: string,\n configDir: string,\n join: string,\n owns: Ownership,\n): ParsedManifest {\n const target = new Map<string, Values>();\n const entries: ExternalMetadataEntry[] = [];\n const lc = new LineCounter();\n // `uniqueKeys: false`, so a document named twice reaches the dedicated\n // check below and is reported by name and line, rather than as a generic\n // \"map keys must be unique\" parse error.\n const doc = parseDocument(text, { lineCounter: lc, uniqueKeys: false });\n const problem = doc.errors[0];\n if (problem) {\n throw new DocmetaError(\n `Manifest ${file} is not valid YAML: ${problem.message}`,\n );\n }\n const root = doc.contents;\n // An empty manifest is a mapping with no entries: legal, and merges nothing.\n if (root === null || (isScalar(root) && root.value === null))\n return { values: target, entries };\n if (!isMap(root)) {\n throw new DocmetaError(\n `Manifest ${file}: the manifest must be a mapping from document ${join === PATH_JOIN ? \"path\" : `\"${join}\"`} to owned keys.`,\n );\n }\n const lineAt = (node: unknown): number | undefined => {\n const range = isNode(node) ? node.range : undefined;\n return range ? lc.linePos(range[0]).line : undefined;\n };\n\n // A document named twice would otherwise resolve last-wins per key, with\n // both entries counted and no diagnostic: `yaml` files a duplicate mapping\n // key under `doc.warnings`, not `doc.errors`. It is almost always a typo,\n // and it is refused by name rather than merged.\n const seen = new Map<string, number | undefined>();\n for (const pair of root.items) {\n const spelled = isScalar(pair.key) ? String(pair.key.value) : String(pair.key);\n const entryLine = lineAt(pair.key);\n const where = entryLine === undefined ? file : `${file}:${entryLine}`;\n if (seen.has(spelled)) {\n const first = seen.get(spelled);\n throw new DocmetaError(\n `Manifest ${where}: \"${spelled}\" is named twice (first at line ${first ?? \"?\"}). Merge the two entries into one.`,\n );\n }\n seen.set(spelled, entryLine);\n if (!isMap(pair.value)) {\n throw new DocmetaError(\n `Manifest ${where}: \"${spelled}\" must be a mapping of owned keys to values.`,\n );\n }\n // A path entry is indexed by its absolute path; a field entry by the\n // spelled value, which a document's field is compared to as a string.\n const indexKey = join === PATH_JOIN ? resolve(configDir, spelled) : spelled;\n const values = target.get(indexKey) ?? new Map<string, ExternalMetadataValue>();\n for (const kv of pair.value.items) {\n const key = isScalar(kv.key) ? String(kv.key.value) : String(kv.key);\n if (key === FILE_SCHEMA_KEY) {\n throw new DocmetaError(\n `Manifest ${where}: \"${spelled}\" sets \"${FILE_SCHEMA_KEY}\" — a manifest never chooses the schema a document is judged by; use \"overrides\" in the config.`,\n );\n }\n if (!owns.may(key)) {\n throw new DocmetaError(`Manifest ${where}: \"${spelled}\" sets \"${key}\", ${owns.why(key)}`);\n }\n const value: unknown =\n kv.value === null\n ? null\n : (kv.value as Node).toJS(doc, { maxAliasCount: 100 });\n const line = lineAt(kv.key);\n const lines = nodeLines(kv.value, lineAt);\n values.set(key, {\n value,\n collection,\n file,\n ...(line === undefined ? {} : { line }),\n ...(lines.size === 0 ? {} : { lines }),\n });\n }\n target.set(indexKey, values);\n entries.push({\n collection,\n join,\n ...(join === PATH_JOIN ? { abs: indexKey } : {}),\n spelled,\n file,\n ...(entryLine === undefined ? {} : { line: entryLine }),\n });\n }\n return { values: target, entries };\n}\n\n/**\n * The line of every node inside one manifest value, keyed by the JSON Pointer\n * relative to that value, RFC 6901 escaped as Ajv's `instancePath` is.\n *\n * A mapping member is recorded at its key's line, the same rule the owned key\n * itself follows, and a list item at the line its node starts: for a block\n * item that is the `- ` line, for a flow item the line its `{` or scalar is\n * on. An alias is recorded where it is written and not followed, so a pointer\n * beneath it falls back to the alias's own line.\n */\nfunction nodeLines(\n node: unknown,\n lineAt: (node: unknown) => number | undefined,\n prefix = \"\",\n out = new Map<string, number>(),\n): Map<string, number> {\n if (isMap(node)) {\n for (const kv of node.items) {\n const seg = isScalar(kv.key) ? String(kv.key.value) : String(kv.key);\n const pointer = `${prefix}/${escapePointerSegment(seg)}`;\n const line = lineAt(kv.key) ?? lineAt(kv.value);\n if (line !== undefined) out.set(pointer, line);\n nodeLines(kv.value, lineAt, pointer, out);\n }\n } else if (isSeq(node)) {\n node.items.forEach((item, i) => {\n const pointer = `${prefix}/${String(i)}`;\n const line = lineAt(item);\n if (line !== undefined) out.set(pointer, line);\n nodeLines(item, lineAt, pointer, out);\n });\n }\n return out;\n}\n\n/** The string a document's join field compares as; undefined when it cannot. */\nfunction joinValue(raw: unknown): string | undefined {\n if (typeof raw === \"string\") return raw;\n if (typeof raw === \"number\" || typeof raw === \"bigint\") return String(raw);\n if (typeof raw === \"boolean\") return String(raw);\n return undefined;\n}\n\n/**\n * Merge the external metadata for one document into its extracted metadata.\n *\n * `label` is the document as the run spells it, relative to `base`; a path\n * entry matches on the resolved absolute path, never on the spelling, so a\n * positional run from a subdirectory finds the same entry a config-corpus\n * run does. A field entry matches on the document's own value of the join\n * field, wherever the document lives. Stdin never matches a path entry:\n * there is no file behind it.\n *\n * `memberOf` names the collections this document belongs to, and only their\n * manifests are consulted (0041 rule 4). It is the caller's `memberOf(...)`\n * result, computed once per file.\n *\n * `present`, `format` and the document's own positions are untouched. A\n * manifest key is not in the document, so `lineFor` keeps answering\n * `undefined` for it, and `locate` answers instead.\n *\n * A join field the page holds encrypted (proposal 0045) is decrypted with\n * `options.encryptionKey` before it is matched. With no key, and a manifest\n * of this document's collections joining on that field, the run cannot match\n * and refuses. A ciphertext that does not decrypt matches nothing.\n */\nexport function mergeExternalMetadata(\n label: string,\n extracted: ExtractedMetadata,\n index: ExternalMetadataIndex | null,\n memberOf: readonly string[],\n base: string,\n options: {\n encryptionKey?: () => string | undefined;\n /**\n * The top-level keys the document's schemas mark `x-manni-location:\n * external` (proposal 0068), which is what a manifest with no `keys`\n * owns. Absent, such a manifest owns nothing for this document.\n */\n marked?: ReadonlySet<string>;\n } = {},\n): MergedMetadata {\n return mergeWith(label, extracted, index, memberOf, base, options.encryptionKey, options.marked ?? UNKNOWN);\n}\n\n/**\n * No marks known: a keyless manifest owns nothing, and a value it holds is\n * skipped rather than refused. Compared by reference, because an explicit\n * empty set means something else: the marks are known and name nothing, so\n * every value a keyless manifest holds for the page is refused.\n */\nconst UNKNOWN: ReadonlySet<string> = new Set();\n\n/**\n * Every value a keyless manifest supplies counts as owned, so the merged data\n * is the probe a page's marks are read over (see `mergeWithMarks`). Nothing\n * is refused or filed in this mode.\n */\nconst PROBE = Symbol(\"probe\");\n\nfunction mergeWith(\n label: string,\n extracted: ExtractedMetadata,\n index: ExternalMetadataIndex | null,\n memberOf: readonly string[],\n base: string,\n encryptionKey: (() => string | undefined) | undefined,\n marked: ReadonlySet<string> | typeof PROBE,\n): MergedMetadata {\n const none = (): undefined => undefined;\n // A file that belongs to no collection gets nothing merged, and carries no\n // collision either: a key only counts as owned by a manifest that applies to\n // this file (0041 rule 4). A positional `README.md` is the case.\n if (!index || memberOf.length === 0) {\n return { extracted, collisions: [], joins: [], locate: none };\n }\n const mine = (collection: string): boolean => memberOf.includes(collection);\n const probing = marked === PROBE;\n\n // The keyless manifests of this file's collections (proposal 0068), and\n // whether one owns a key for this file.\n const implied = (impliedOwners.get(index) ?? []).filter((o) => mine(o.collection.name));\n const impliedOwns = (o: ImpliedOwner, key: string): boolean =>\n probing ? !neverOwned(o.collection, o.manifest).has(key) : ownsKey(o.collection, o.manifest, key, marked);\n /** Every manifest of this file's collections that owns `key` for it. Not asked while probing. */\n const ownersOf = (key: string): { collection: string; file: string }[] =>\n pageOwners(index, key, memberOf, probing ? undefined : marked);\n /** The keyless manifest a value came from, when one did. */\n const impliedFrom = (sv: ExternalMetadataValue): ImpliedOwner | undefined =>\n implied.find((o) => o.collection.name === sv.collection && o.files.has(sv.file));\n\n const collisions: ExternalMetadataCollision[] = [];\n if (!probing) {\n for (const key of Object.keys(extracted.data)) {\n for (const owner of ownersOf(key)) {\n collisions.push({ key, file: owner.file, collection: owner.collection });\n }\n }\n }\n\n const sources: ReadonlyMap<string, ExternalMetadataValue>[] = [];\n /** The manifest entry a source's values came from, for a refusal that names it. */\n const entryOf = new Map<ReadonlyMap<string, ExternalMetadataValue>, (sv: ExternalMetadataValue) => ExternalMetadataEntry | undefined>();\n const joins: ExternalMetadataJoin[] = [];\n if (label !== STDIN_LABEL) {\n const byPath = index.byPath.get(resolve(base, label));\n if (byPath) {\n sources.push(byPath);\n const abs = resolve(base, label);\n entryOf.set(byPath, (sv) => index.entries.find((e) => e.file === sv.file && e.abs === abs));\n }\n }\n for (const [field, byValue] of index.byField) {\n const raw = extracted.data[field];\n let value: string | undefined;\n let pageValue: string | undefined;\n if (isEncryptedValue(raw)) {\n const joinsHere = [...byValue.values()].some((supplied) =>\n [...supplied.values()].some((sv) => mine(sv.collection)),\n );\n if (!joinsHere) continue;\n const key = encryptionKey?.();\n if (key === undefined) {\n throw new EncryptionRefusal(\n `externalMetadata join field \"${field}\" is encrypted on these pages, and no encryption key is available to match them.`,\n );\n }\n const opened = decryptValue(raw, key, META_CONTEXT);\n if (!opened.ok) continue;\n value = joinValue(opened.value);\n pageValue = raw;\n } else {\n value = joinValue(raw);\n }\n if (value === undefined) continue;\n const hit = byValue.get(value);\n if (!hit) continue;\n sources.push(hit);\n const spelled = value;\n entryOf.set(hit, (sv) =>\n index.entries.find((e) => e.file === sv.file && e.join === field && e.spelled === spelled),\n );\n // Exactly one join per (field, value), whatever the collections behind it.\n // The duplicate-join finding (0039) counts *documents* per value, so a\n // second entry for one document would read as a second document.\n const first = [...hit.values()].find((sv) => mine(sv.collection));\n if (first) {\n joins.push({\n field,\n value,\n ...(pageValue === undefined ? {} : { pageValue }),\n file: first.file,\n collection: first.collection,\n });\n }\n }\n\n // Two of this file's collections owning one key the manifests actually\n // supply for it is an operational error, not a finding: there is nothing\n // about the document to fix, and picking a winner would be the tiebreak\n // 0020 and 0037 both refuse (0041 rule 5). The legitimate case — two\n // collections each owning `owner`, with no file in both — is untouched,\n // which is why this is decided per file rather than at parse time.\n for (const supplied of probing ? [] : sources) {\n for (const key of supplied.keys()) {\n const [a, b] = ownersOf(key);\n if (a && b) {\n throw new DocmetaError(\n `${label}: \"${key}\" is owned by manifests in two of its collections, ${a.collection} (${a.file}) and ${b.collection} (${b.file}); a key has one manifest per file. Narrow one collection's paths or exclude.`,\n );\n }\n }\n }\n\n if (sources.length === 0) {\n return { extracted, collisions, joins, locate: none };\n }\n\n const data: Record<string, unknown> = { ...extracted.data };\n const merged = new Map<string, ExternalMetadataValue>();\n for (const supplied of sources) {\n for (const [key, sv] of supplied) {\n // Only the manifests of collections this file belongs to.\n if (!mine(sv.collection)) continue;\n // A keyless manifest owns only what this file's schemas mark external\n // (0068 rule 5). An entry carrying anything else sets a key nothing\n // owns, which is the refusal a manifest with keys gives for one. With\n // the marks unknown (the schema set did not resolve, or the caller\n // passed none), nothing is owned and nothing is judged.\n const from = impliedFrom(sv);\n if (from !== undefined && !impliedOwns(from, key)) {\n if (probing || marked === UNKNOWN) continue;\n throw unmarkedRefusal(label, key, sv, entryOf.get(supplied)?.(sv));\n }\n // The document's value stays: the collision is filed by the caller,\n // and the report should show what the public site would publish.\n if (key in extracted.data) continue;\n data[key] = sv.value;\n merged.set(key, sv);\n }\n }\n const locate = (pointer: string): SourceLocation | undefined => {\n const split = splitTopLevel(pointer);\n if (split === undefined) return undefined;\n const sv = merged.get(split.key);\n if (!sv) return undefined;\n const line = manifestLine(sv, split.rest);\n return { file: sv.file, ...(line === undefined ? {} : { line }) };\n };\n return { extracted: { ...extracted, data }, collisions, joins, locate };\n}\n\n/**\n * The refusal for a keyless manifest's entry that sets a field the page's\n * schemas do not mark external (proposal 0068). It is the unowned-key refusal\n * a manifest with `keys` gives when it is read, said per page because what a\n * keyless manifest owns is.\n */\nfunction unmarkedRefusal(\n label: string,\n key: string,\n sv: ExternalMetadataValue,\n entry: ExternalMetadataEntry | undefined,\n): DocmetaError {\n const line = entry?.line ?? sv.line;\n const where = line === undefined ? sv.file : `${sv.file}:${String(line)}`;\n const spelled = entry?.spelled ?? label;\n return new DocmetaError(\n `Manifest ${where}: \"${spelled}\" sets \"${key}\", which this manifest does not own, because the page's schemas do not mark it x-manni-location: external. Mark it external in the page's schemas, or remove it from the entry.`,\n );\n}\n\n/**\n * The top-level keys one document's schemas mark `x-manni-location:\n * external`, read over `probe`: the document's metadata with everything its\n * keyless manifests supply for it (proposal 0068). `undefined` when the\n * document's schemas cannot be resolved or loaded, so the caller reports that\n * the way it always has and a keyless manifest owns nothing for it.\n */\nexport type PageMarks = (\n label: string,\n probe: Readonly<Record<string, unknown>>,\n memberOf: readonly string[],\n) => Promise<ReadonlySet<string> | undefined>;\n\n/** `mergeExternalMetadata`'s result, with the marks it was merged under. */\nexport interface MarkedMerge extends MergedMetadata {\n /** What the document's schemas mark external, when a keyless manifest needed asking. */\n marked?: ReadonlySet<string>;\n}\n\n/**\n * `mergeExternalMetadata`, with a keyless manifest's ownership settled first\n * (proposal 0068). Every command that merges goes through here, so what such\n * a manifest owns for a page is decided one way.\n *\n * The marks are read only when one of the document's collections declares a\n * manifest with no `keys`, which no config written before 0068 does, so\n * those runs never load a schema to merge. They are read over the document\n * with every value its keyless manifests supply, because a mark counts only\n * where Ajv evaluates it, and Ajv evaluates a property that is present.\n */\nexport async function mergeWithMarks(\n label: string,\n extracted: ExtractedMetadata,\n index: ExternalMetadataIndex | null,\n memberOf: readonly string[],\n base: string,\n options: { encryptionKey?: () => string | undefined; marks?: PageMarks },\n): Promise<MarkedMerge> {\n const { encryptionKey, marks } = options;\n if (marks === undefined || !hasImpliedOwner(index, memberOf)) {\n return mergeWith(label, extracted, index, memberOf, base, encryptionKey, UNKNOWN);\n }\n // First pass: include the keyless manifests' values, because a schema's\n // `x-manni-location` marks only fire on keys that are present.\n const probe = mergeWith(label, extracted, index, memberOf, base, encryptionKey, PROBE).extracted.data;\n const marked = await marks(label, probe, memberOf);\n // With the page's schema set unresolvable, the probe was spent for\n // nothing, and the merge below is the one a keyless-free collection gets.\n const merged = mergeWith(label, extracted, index, memberOf, base, encryptionKey, marked ?? UNKNOWN);\n return marked === undefined ? merged : { ...merged, marked };\n}\n\n/** Does one of these collections declare a manifest with no `keys` in this index? */\nexport function hasImpliedOwner(\n index: ExternalMetadataIndex | null,\n memberOf: readonly string[],\n): boolean {\n if (index === null) return false;\n return (impliedOwners.get(index) ?? []).some((o) => memberOf.includes(o.collection.name));\n}\n\n/**\n * The manifest line of `rest`, a pointer inside one supplied value: the\n * deepest node it reaches, else the nearest recorded ancestor, else the owned\n * key's own line. The same walk-up rule a document's `lineFor` follows.\n */\nfunction manifestLine(sv: ExternalMetadataValue, rest: string): number | undefined {\n if (rest === \"\" || sv.lines === undefined) return sv.line;\n return positionForFactory(sv.lines)(rest) ?? sv.line;\n}\n\n/**\n * The top-level key a pointer (or bare key) addresses, unescaped, and the\n * still-escaped pointer beneath it. Undefined for the root.\n */\nfunction splitTopLevel(pointer: string): { key: string; rest: string } | undefined {\n if (pointer === \"\") return undefined;\n if (!pointer.startsWith(\"/\")) return { key: pointer, rest: \"\" };\n const slash = pointer.indexOf(\"/\", 1);\n const seg = slash < 0 ? pointer.slice(1) : pointer.slice(1, slash);\n return {\n key: seg.replace(/~1/g, \"/\").replace(/~0/g, \"~\"),\n rest: slash < 0 ? \"\" : pointer.slice(slash),\n };\n}\n\n/** The `/key` pointer for an external-metadata finding, RFC 6901 escaped. */\nexport function externalMetadataPointer(key: string): string {\n return `/${escapePointerSegment(key)}`;\n}\n\n/**\n * Path entries naming no loaded document.\n *\n * `loaded` are the run's file labels, relative to `base`. Checked only when\n * the run is the config corpus (the same invariant corpus checks use): a\n * positional path means the operator chose to look at part of the corpus,\n * and an entry for the rest is expected, not orphaned.\n *\n * A `{page}` entry (proposal 0058) is never orphaned inside a file the run\n * read, because each file is named after its page. Its orphan is a stray\n * *file*, left behind by a `git mv` or a deletion, so on a run with no\n * `collections` narrowing the pattern's glob is walked and every manifest of\n * a page the run did not load is reported after the entries above. A\n * `--collection` run skips the walk: another collection's pages, which it\n * did not load, could share the pattern.\n */\nexport function orphanEntries(\n index: ExternalMetadataIndex | null,\n loaded: readonly string[],\n base: string,\n collections?: readonly string[],\n): ExternalMetadataEntry[] {\n if (!index) return [];\n const have = new Set(loaded.map((l) => resolve(base, l)));\n const orphans = index.entries.filter(\n (e) =>\n inCollections(e, collections) &&\n e.join === PATH_JOIN &&\n e.abs !== undefined &&\n !have.has(e.abs),\n );\n if (collections !== undefined) return orphans;\n return [...orphans, ...strayManifests(perPageRules.get(index) ?? [], have, base)];\n}\n\n/**\n * Manifests a `{page}` pattern names on disk for pages the run did not load\n * (0058 § 5), one orphan per entry. A file some loaded page resolves to was\n * read and checked by the loader, so it is not walked into again.\n */\nfunction strayManifests(\n rules: readonly PerPageRule[],\n loaded: ReadonlySet<string>,\n base: string,\n): ExternalMetadataEntry[] {\n const strays: ExternalMetadataEntry[] = [];\n for (const { collection, manifest, configDir } of rules) {\n const read = new Set<string>();\n for (const pageAbs of loaded) {\n const resolved = pageManifestPath(manifest.file, configDir, pageAbs);\n if (!(\"outside\" in resolved)) read.add(resolved.abs);\n }\n const found = findPageManifests(manifest.file, configDir, (rel) => isMember(collection, rel), read);\n for (const { abs, entries } of found) {\n const file = reportedPath(abs, base);\n for (const entry of entries) {\n if (loaded.has(entry.pageAbs)) continue;\n const stray: ExternalMetadataEntry = {\n collection: collection.name,\n join: PATH_JOIN,\n abs: entry.pageAbs,\n spelled: entry.spelled,\n file,\n ...(entry.line === undefined ? {} : { line: entry.line }),\n };\n strayEntries.add(stray);\n strays.push(stray);\n }\n }\n }\n return strays;\n}\n\n/**\n * Is this entry's collection one the run covers whole?\n *\n * `undefined` means every collection, which is a run with no `--collection`.\n * Naming collections makes each named one its own corpus (proposal 0041 rule\n * 6): the run loaded all of it, so an entry of that collection pointing at a\n * document that is not there is as orphaned as it would be in a full run. An\n * entry belonging to a collection nobody selected is not — the run never\n * claimed to cover it.\n */\nfunction inCollections(\n entry: ExternalMetadataEntry,\n collections: readonly string[] | undefined,\n): boolean {\n return collections === undefined || collections.includes(entry.collection);\n}\n\n/**\n * Field entries no loaded document matched (0039). `matched` is field -> the\n * values documents in the run carried, which the caller collects from each\n * document's `joins` — so this runs after the per-file loop, under the same\n * corpus invariant as `orphanEntries`.\n */\nexport function orphanJoins(\n index: ExternalMetadataIndex | null,\n matched: ReadonlyMap<string, ReadonlySet<string>>,\n collections?: readonly string[],\n): ExternalMetadataEntry[] {\n if (!index) return [];\n return index.entries.filter(\n (e) =>\n inCollections(e, collections) &&\n e.join !== PATH_JOIN &&\n !(matched.get(e.join)?.has(e.spelled) ?? false),\n );\n}\n\n/** The operational error an orphan check raises, naming the first entry. */\nexport function orphanError(orphans: readonly ExternalMetadataEntry[]): DocmetaError {\n const first = orphans[0];\n if (!first) throw new Error(\"orphanError called with no orphans\");\n const where = first.line === undefined ? first.file : `${first.file}:${first.line}`;\n const more = orphans.length > 1 ? ` (${orphans.length - 1} more)` : \"\";\n const what =\n first.join === PATH_JOIN\n ? `names \"${first.spelled}\", which this run did not load`\n : `names ${first.join} \"${first.spelled}\", which no loaded document carries`;\n // A stray per-page file holds its one page's entry, so the file goes with it.\n const remove = strayEntries.has(first) ? \"the file\" : \"it\";\n return new DocmetaError(\n `Manifest ${where} ${what}${more}. Fix the entry, or remove ${remove}.`,\n );\n}\n\n/**\n * Every manifest of `memberOf`'s collections that owns `key` for one page:\n * those whose `keys` name it, and a keyless one (proposal 0068) when `marked`,\n * the page's external marks, holds it. Empty when none does.\n */\nexport function pageOwners(\n index: ExternalMetadataIndex | null,\n key: string,\n memberOf: readonly string[],\n marked: ReadonlySet<string> | undefined,\n): { collection: string; file: string }[] {\n if (index === null) return [];\n return [\n ...(index.owners.get(key) ?? []).filter((o) => memberOf.includes(o.collection)),\n ...(impliedOwners.get(index) ?? [])\n .filter((o) => memberOf.includes(o.collection.name) && ownsKey(o.collection, o.manifest, key, marked))\n .map((o) => ({ collection: o.collection.name, file: o.file })),\n ];\n}\n","/**\n * Compare-and-swap for a manifest a command rewrites in memory.\n *\n * Every tool that writes external metadata does the same thing. It reads a\n * manifest once, splices the entries it owns into the text it read, and writes\n * the whole file back seconds later, after the minting or hashing or model\n * round trips that made the values. Two commands over one working copy overlap\n * inside that gap easily, and each writes bytes derived from a read that\n * predates the other, so the second write replaces the first's entries with\n * bytes that never had them. Nothing reports it: the loser's entries simply\n * are not there, and a manifest short of an entry reads as a file nobody\n * recorded anything about.\n *\n * So the write is a compare-and-swap. The run keeps, beside the text it is\n * building, the edits it made as plain descriptors and the value each entry's\n * key held when it first touched it. The write re-reads, writes when the bytes\n * are the ones it spliced from, and otherwise replays the descriptors onto the\n * newer bytes and looks again. A replay keeps the other run's entries, because\n * each edit replaces one range of the text it is given and leaves every other\n * byte alone. A key both runs wrote cannot be replayed, because the value this\n * run computed was derived from the other one's absence, so that is a refusal\n * rather than a silent merge.\n *\n * The conflict base is one entry's one key, not the whole entry. `meta fill`\n * writing `summary` and `meta derive` writing `updated` into one page's entry\n * are not in conflict, and a base keyed on the entry alone would refuse them\n * both.\n *\n * What this module cannot own is the splice itself. Reading and rewriting one\n * key of a manifest is the metadata tool's, and the shared layer does not\n * import a tool's module (`write-file.ts` states the rule), so the caller\n * hands in an `apply` and a `read` and this file owns only hold, re-read,\n * replay and refuse.\n *\n * This narrows the window rather than closing it: nothing stops a third write\n * landing between the re-read and the rename. The window goes from the length\n * of a whole command to the microseconds around one `rename`, which is what a\n * lock file would have to justify itself against.\n */\nimport { readFile } from \"node:fs/promises\";\nimport { posix } from \"node:path\";\n\n/** One entry's one key: what an edit rewrites, and what a conflict is about. */\nexport interface ManifestKey {\n /** The entry, as the manifest spells it. */\n entry: string;\n /** The key of that entry the edit rewrites. */\n key: string;\n /** How entry keys are compared; `path` normalizes separators. */\n join: string;\n}\n\n/** One edit a run made, replayable onto bytes read later. */\nexport interface ManifestOp extends ManifestKey {\n /** The manifest as the run names it in its own messages. */\n file: string;\n}\n\n/**\n * The two halves of a manifest this loop cannot own: applying one recorded\n * edit to whatever text it is handed, and reading one entry's key back out of\n * text the run has not seen before.\n */\nexport interface ManifestCodec<Op extends ManifestOp> {\n /** One recorded edit, against whatever text it is handed. */\n apply: (text: string, op: Op) => string;\n /** One entry's key as the given text holds it, or `undefined` when absent. */\n read: (text: string, at: ManifestKey) => unknown;\n}\n\n/** An entry's key this run rewrote, and what it held before the run did. */\ninterface KeyBase extends ManifestKey {\n /** The value as it was read, encoded so absence cannot collide. */\n value: string;\n}\n\n/** One manifest held for the length of a run: its text before, and now. */\nexport interface HeldManifest<Op extends ManifestOp> {\n /** Absolute path, the write target. */\n path: string;\n /** The manifest as the run reports it. */\n file: string;\n /** The bytes the run's edits were computed from. */\n before: string;\n /** The bytes as the run has rewritten them. */\n text: string;\n /** Every edit this run made, in order, for a replay onto newer bytes. */\n ops: Op[];\n /** Each entry key this run rewrote, and what it held first. */\n bases: Map<string, KeyBase>;\n /**\n * The file did not exist when it was held, so `before` is empty text\n * standing in for no file (proposal 0058). A distinct state from a file\n * that exists and is empty: a commit that still finds nothing creates the\n * file, and one that finds any bytes, empty ones included, rebases onto\n * them, since another writer created it in between.\n */\n absent: boolean;\n}\n\n/** How many times a write re-reads and replays before it refuses. */\nexport const COMMIT_ATTEMPTS = 5;\n\n/** The refusal when a manifest will not hold still long enough to be written. */\nexport function conflictRefusal(file: string): string {\n return `${file} changed under the command while it was being written. Nothing was written to it. Re-run the command.`;\n}\n\n/**\n * A manifest read, ready to be spliced and later settled. `absent` holds a\n * file that does not exist yet, with `before` as the empty text it stands in\n * for; only a per-page manifest (proposal 0058) is ever held that way.\n */\nexport function heldManifest<Op extends ManifestOp>(\n path: string,\n file: string,\n before: string,\n absent = false,\n): HeldManifest<Op> {\n return { path, file, before, text: before, ops: [], bases: new Map(), absent };\n}\n\n/**\n * A value as read, or the absence of one, as one comparable string.\n * `JSON.stringify` never answers a bare word, so `absent` cannot collide with\n * a value an entry actually holds.\n */\nfunction encodeValue(value: unknown): string {\n return value === undefined ? \"absent\" : JSON.stringify(value);\n}\n\n/** An entry and a key as one map key, spelled the way the manifest joins. */\nfunction baseKey(at: ManifestKey): string {\n const entry = at.join === \"path\" ? posix.normalize(at.entry) : at.entry;\n return `${entry}\\u0000${at.key}`;\n}\n\n/** Note what an entry's key held before this run first rewrote it. */\nexport function rebaseable<Op extends ManifestOp>(\n held: HeldManifest<Op>,\n op: Op,\n codec: ManifestCodec<Op>,\n): void {\n const at = baseKey(op);\n if (held.bases.has(at)) return;\n held.bases.set(at, {\n entry: op.entry,\n key: op.key,\n join: op.join,\n value: encodeValue(codec.read(held.before, op)),\n });\n}\n\n/**\n * Replay this run's edits onto the manifest as it now stands, or `undefined`\n * when a key this run rewrote has changed since it was read. Each edit\n * replaces one range of the text it is given, so every entry this run did not\n * touch survives the replay untouched.\n */\nexport function rebase<Op extends ManifestOp>(\n held: HeldManifest<Op>,\n current: string,\n codec: ManifestCodec<Op>,\n): string | undefined {\n for (const base of held.bases.values()) {\n if (encodeValue(codec.read(current, base)) !== base.value) return undefined;\n }\n let text = current;\n for (const op of held.ops) text = codec.apply(text, op);\n return text;\n}\n\n/**\n * Take the bytes just written as the new base, so a run that writes one\n * manifest more than once compares its next write against what it left on\n * disk. Without it the second write would replay against the pre-run text and\n * call this run's own first write somebody else's.\n */\nexport function rebaseline<Op extends ManifestOp>(held: HeldManifest<Op>): void {\n held.before = held.text;\n held.ops = [];\n held.bases.clear();\n held.absent = false;\n}\n\n/** What `settle` needs from the tool around it. */\nexport interface SettleIo<Op extends ManifestOp> {\n /** Applying and reading one edit; the metadata tool's, handed in. */\n codec: ManifestCodec<Op>;\n /** The byte writer; an atomic write unless a test says otherwise. */\n write: (path: string, text: string) => Promise<void>;\n /**\n * The compare-and-swap re-read, for a test counting the retries. It is that\n * loop's read alone: the first read of a manifest is the caller's.\n */\n read: (path: string) => Promise<string>;\n /** The calling tool's error class, so a refusal reads as that tool's. */\n toError: (message: string) => Error;\n}\n\n/**\n * Write one manifest, re-reading it first so the bytes being replaced are the\n * bytes this run spliced from. A run that loses the compare replays its edits\n * onto what it found and looks again; one that keeps losing refuses, having\n * written nothing.\n */\nexport async function settle<Op extends ManifestOp>(\n held: HeldManifest<Op>,\n io: SettleIo<Op>,\n): Promise<void> {\n for (let attempt = 1; attempt <= COMMIT_ATTEMPTS; attempt++) {\n let current: string;\n try {\n current = await io.read(held.path);\n } catch (error) {\n // Held absent and still missing: this run creates the file. A file that\n // was present when it was held and is gone now is a refusal, as it\n // always was, because something removed it on purpose.\n if (held.absent && isMissing(error)) {\n await io.write(held.path, held.text);\n held.absent = false;\n return;\n }\n const reason = error instanceof Error ? error.message : String(error);\n throw io.toError(`Manifest ${held.file} could not be read: ${reason}`);\n }\n // Bytes where the run held none are another writer's file, even empty\n // ones, so they are rebased onto rather than written over.\n if (!held.absent && current === held.before) {\n await io.write(held.path, held.text);\n return;\n }\n const replayed = rebase(held, current, io.codec);\n // A replay that cannot be made is a verdict about bytes just read, against\n // a base fixed when this run first touched the key. Neither side of that\n // comparison moves on a re-read, so the attempts are left for the case\n // they exist for, which is a file moving under replays that do succeed.\n if (replayed === undefined) throw io.toError(conflictRefusal(held.file));\n held.before = current;\n held.text = replayed;\n held.absent = false;\n }\n throw io.toError(conflictRefusal(held.file));\n}\n\n/** A read that failed because nothing is there. */\nexport function isMissing(error: unknown): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"ENOENT\";\n}\n\n/**\n * A manifest's bytes, read just before a writer splices into them. A per-page\n * manifest (proposal 0058) that is not on disk yet is a page with nothing\n * recorded: it reads as empty text, and the write creates it. A missing\n * concrete manifest, or any other failure, is thrown for the caller to report\n * in its own error class.\n */\nexport async function readManifestOrEmpty(absPath: string, perPage: boolean): Promise<string> {\n try {\n return await readFile(absPath, \"utf8\");\n } catch (e) {\n if (perPage && isMissing(e)) return \"\";\n throw e;\n }\n}\n\n/** What a caller may substitute when it writes the manifests it held. */\nexport interface CommitIo<Change> {\n /** The byte writer; an atomic write unless a test says otherwise. */\n write?: (path: string, text: string) => Promise<void>;\n /** The compare-and-swap re-read, for a test counting the retries. */\n read?: (path: string) => Promise<string>;\n /** Called after each manifest lands, in write order. */\n after?: (change: Change) => void;\n /** Called when one manifest fails to land; must throw. */\n onError?: (change: Change, error: unknown) => Promise<never>;\n}\n","/**\n * Fetch a remote manifest (proposal 0038).\n *\n * A manifest named by URL is fetched at the start of every run and never\n * cached: it is data that changes with every page, and a stale copy validates\n * the corpus against the wrong values. The bounds are the schema fetch's —\n * the same timeout, the same body cap, one narrow retry — because they exist\n * for the same reason there (0008 § stress test 4), and a manifest is\n * smaller than most schemas.\n *\n * The credential, when there is one, comes from the environment and is sent\n * as a bearer token to the origin the config named and nowhere else. It\n * never appears in a message: every error here names the URL and the status,\n * and the URL was checked at config time to carry no userinfo.\n */\nimport { DocmetaError } from \"../types.js\";\n\n/** Default network timeout, matching the schema fetch. */\nexport const EXTERNAL_METADATA_FETCH_TIMEOUT_MS = 10_000;\n\n/** Body cap, matching the schema fetch. */\nexport const EXTERNAL_METADATA_FETCH_MAX_BYTES = 5 * 1024 * 1024;\n\n/** Redirects followed before giving up. */\nconst MAX_REDIRECTS = 5;\n\n/** Backoff before the single retry. */\nconst RETRY_DELAY_MS = 500;\n\nexport interface ExternalMetadataFetchOptions {\n /** Environment variable holding a bearer token. Absent means an anonymous request. */\n tokenEnv?: string;\n timeoutMs?: number;\n maxBytes?: number;\n /** `--offline` / `offline:`: refuse rather than fetch. */\n offline?: boolean;\n /** For tests: the environment to read `tokenEnv` from. Defaults to `process.env`. */\n env?: Record<string, string | undefined>;\n}\n\n/** Fetch one remote manifest. Resolves to its text; throws `DocmetaError`. */\nexport async function fetchExternalMetadata(\n url: string,\n opts: ExternalMetadataFetchOptions = {},\n): Promise<string> {\n if (opts.offline) {\n throw new DocmetaError(\n `Manifest ${url} is remote and the run is offline. Vendor it to a path, or drop --offline.`,\n );\n }\n const timeoutMs = opts.timeoutMs ?? EXTERNAL_METADATA_FETCH_TIMEOUT_MS;\n const maxBytes = opts.maxBytes ?? EXTERNAL_METADATA_FETCH_MAX_BYTES;\n const env = opts.env ?? process.env;\n let token: string | undefined;\n if (opts.tokenEnv !== undefined) {\n token = env[opts.tokenEnv];\n if (token === undefined || token === \"\") {\n throw new DocmetaError(\n `Manifest ${url}: the environment variable ${opts.tokenEnv} named by \"tokenEnv\" is not set.`,\n );\n }\n }\n\n let res = await requestWithRedirects(url, token, timeoutMs);\n // One retry, on the failures that can heal: a network error or a 5xx. A\n // 4xx will not, and retrying it only doubles the time to the same answer.\n if (res instanceof Error || res.status >= 500) {\n await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));\n res = await requestWithRedirects(url, token, timeoutMs);\n }\n if (res instanceof Error) {\n throw new DocmetaError(\n `Manifest ${url} could not be fetched: ${res.message}`,\n );\n }\n if (!res.ok) {\n const hint =\n res.status === 404 && token === undefined\n ? \" (a private file answers 404 without a token; set \\\"tokenEnv\\\")\"\n : res.status === 404\n ? \" (a private file answers 404 without a valid token)\"\n : \"\";\n throw new DocmetaError(\n `Manifest ${url} could not be fetched: HTTP ${res.status}${hint}.`,\n );\n }\n return readCapped(url, res, maxBytes);\n}\n\n/**\n * GET with manual redirect handling, so the bearer token follows only a\n * same-origin redirect. A cross-origin hop is followed without it, the way\n * browsers and curl behave; if the manifest lives where the token does not\n * reach, the 401 that results is reported rather than the token leaked.\n *\n * Resolves to the final `Response`, or to the `Error` a network failure or\n * timeout raised, so the caller can decide what to retry.\n */\nasync function requestWithRedirects(\n url: string,\n token: string | undefined,\n timeoutMs: number,\n): Promise<Response | Error> {\n const origin = new URL(url).origin;\n let current = url;\n for (let hop = 0; hop <= MAX_REDIRECTS; hop++) {\n const sameOrigin = new URL(current).origin === origin;\n const headers: Record<string, string> = { accept: \"text/plain, application/x-yaml, */*\" };\n if (token !== undefined && sameOrigin) headers.authorization = `Bearer ${token}`;\n let res: Response;\n try {\n res = await fetch(current, {\n headers,\n redirect: \"manual\",\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (err) {\n const isAbort = err instanceof Error && err.name === \"TimeoutError\";\n return isAbort\n ? new Error(`timed out after ${timeoutMs}ms`)\n : new Error(err instanceof Error ? err.message : String(err));\n }\n if (res.status >= 300 && res.status < 400) {\n const location = res.headers.get(\"location\");\n if (location === null) return res;\n await res.body?.cancel();\n current = new URL(location, current).toString();\n continue;\n }\n return res;\n }\n return new Error(`more than ${MAX_REDIRECTS} redirects`);\n}\n\n/** Read a body, aborting once it exceeds `maxBytes`; content-length is advisory. */\nasync function readCapped(\n url: string,\n res: Response,\n maxBytes: number,\n): Promise<string> {\n const body = res.body;\n if (!body) return \"\";\n // `Response.body` is typed `ReadableStream<any>`; name the chunk type once\n // at the boundary, as the schema fetch does, so the cap is counted in\n // numbers rather than `any` arithmetic.\n const reader = body.getReader() as ReadableStreamDefaultReader<Uint8Array>;\n const chunks: Uint8Array[] = [];\n let total = 0;\n for (;;) {\n const { done, value }: { done: boolean; value?: Uint8Array } =\n await reader.read();\n if (done || value === undefined) break;\n total += value.byteLength;\n if (total > maxBytes) {\n await reader.cancel();\n throw new DocmetaError(\n `Manifest ${url} is too large: the response exceeds the ${maxBytes}-byte limit.`,\n );\n }\n chunks.push(value);\n }\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n","/**\n * The family encryption key (proposal 0045): where a run finds it, where a\n * write puts it, and whether git would publish it.\n *\n * One key for the family, at the top of `manni.config.yaml` beside\n * `collections:`, read by every tool. `MANNI_ENCRYPTION_KEY` in the\n * environment wins over it, which is the right home for a shared repository:\n * a key committed with the pages decrypts every value on them.\n */\nimport { spawnSync } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\nimport { basename, dirname, join, relative, resolve } from \"node:path\";\nimport { isDeepStrictEqual } from \"node:util\";\nimport { isMap, parseDocument, parse as parseYaml, stringify } from \"yaml\";\nimport {\n ENCRYPTION_KEY_FIELD,\n ENCRYPTION_KEY_PREVIOUS_FIELD,\n FAMILY_CONFIG_NAMES,\n type ConfigFile,\n} from \"./config-file.js\";\nimport { isValidEncryptionKey } from \"./encryption.js\";\nimport { findGitRoot } from \"./git-root.js\";\nimport { writeTextAtomic } from \"./write-file.js\";\n\nexport {\n ENCRYPTION_KEY_FIELD,\n ENCRYPTION_KEY_PREVIOUS_FIELD,\n findFamilyConfigFile,\n readFamilyConfigFile,\n} from \"./config-file.js\";\n\n/** The environment variable that wins over the config's key. */\nexport const ENCRYPTION_KEY_ENV = \"MANNI_ENCRYPTION_KEY\";\n\nexport type KeySource = \"env\" | \"config\" | \"none\";\n\nexport interface ResolvedKey {\n key: string | undefined;\n source: KeySource;\n}\n\ntype ToError = (message: string) => Error;\n\n/**\n * The key a run uses: the environment's, else the config file's, else none.\n *\n * An empty `MANNI_ENCRYPTION_KEY` counts as unset, because that is what an\n * absent CI secret expands to (a fork's pull request, say), and refusing the\n * run there would fail every such build for a key it was never going to get.\n * A non-empty value of the wrong shape is refused, and never echoed.\n */\nexport function resolveEncryptionKey(opts: {\n env?: NodeJS.ProcessEnv;\n file: ConfigFile | null;\n toError: ToError;\n}): ResolvedKey {\n const env = opts.env ?? process.env;\n const fromEnv = env[ENCRYPTION_KEY_ENV];\n if (fromEnv !== undefined && fromEnv !== \"\") {\n if (!isValidEncryptionKey(fromEnv)) {\n throw opts.toError(\n `${ENCRYPTION_KEY_ENV} must be at least 32 hex or base64url characters.`,\n );\n }\n return { key: fromEnv, source: \"env\" };\n }\n const fromFile = opts.file?.encryptionKey;\n if (fromFile !== undefined) return { key: fromFile, source: \"config\" };\n return { key: undefined, source: \"none\" };\n}\n\ninterface Target {\n path: string;\n source: string;\n /** The file's current text, or `null` when the write creates it. */\n text: string | null;\n}\n\nfunction relativeSource(cwd: string, path: string): string {\n return relative(resolve(cwd), path).replace(/\\\\/g, \"/\");\n}\n\nfunction errorCode(err: unknown): string | undefined {\n return typeof err === \"object\" && err !== null && \"code\" in err\n ? String(err.code)\n : undefined;\n}\n\nasync function readIfPresent(path: string): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch (err) {\n if (errorCode(err) === \"ENOENT\") return null;\n throw err;\n }\n}\n\nasync function fileTarget(file: ConfigFile, toError: ToError): Promise<Target> {\n // A single-tool file's whole document is one tool's section. A top-level\n // `encryptionKey:` would turn it into a family file on the next read, and\n // every key the tool had would stop being read.\n if (file.kind === \"legacy\" || !file.wrapped) {\n throw toError(\n `${file.source} is a single-tool config file, which cannot hold the family ${ENCRYPTION_KEY_FIELD}. Move its keys under the tool's section in ${FAMILY_CONFIG_NAMES[0] ?? \"manni.config.yaml\"}, or set ${ENCRYPTION_KEY_ENV}.`,\n );\n }\n // Re-read rather than trust `file.text`: the file may have changed since\n // discovery, and an edit made in between must not be written over.\n const text = await readIfPresent(file.path);\n return { path: file.path, source: file.source, text: text ?? file.text };\n}\n\n/**\n * With no config for the running tool, the key goes to the git root (else\n * `cwd`), where discovery from anywhere in the repository finds it. A family\n * file already there, one a sibling tool owns, is edited rather than\n * replaced.\n */\nasync function defaultTarget(cwd: string): Promise<Target> {\n const root = findGitRoot(cwd) ?? resolve(cwd);\n for (const name of FAMILY_CONFIG_NAMES) {\n const path = join(root, name);\n const text = await readIfPresent(path);\n if (text !== null) return { path, source: relativeSource(cwd, path), text };\n }\n const path = join(root, FAMILY_CONFIG_NAMES[0] ?? \"manni.config.yaml\");\n return { path, source: relativeSource(cwd, path), text: null };\n}\n\n/**\n * What a write does with `encryptionKeyPrevious:`: a string sets it, `null`\n * removes it, and `undefined` leaves whatever is there.\n */\ntype Previous = string | null | undefined;\n\n/** `text` with the top-level keys set, comments and key order kept. */\nfunction withKey(\n text: string,\n key: string,\n previous: Previous,\n source: string,\n toError: ToError,\n): string {\n const doc = parseDocument(text);\n const [first] = doc.errors;\n if (first !== undefined) {\n throw toError(`${source}: invalid YAML: ${first.message}`);\n }\n if (doc.contents !== null && !isMap(doc.contents)) {\n throw toError(`${source}: top level must be a mapping.`);\n }\n // Replaces an existing key in place, appends a new one, and turns an empty\n // or comment-only document into a one-key mapping.\n doc.set(ENCRYPTION_KEY_FIELD, key);\n if (typeof previous === \"string\") doc.set(ENCRYPTION_KEY_PREVIOUS_FIELD, previous);\n if (previous === null) doc.delete(ENCRYPTION_KEY_PREVIOUS_FIELD);\n return doc.toString();\n}\n\nfunction isMapping(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Read back what is about to be written: the key, and every other top-level\n * value exactly as it was. A config the tools cannot read, or one that lost a\n * key on the way, is worse than a refused write.\n */\nfunction verify(\n before: string | null,\n after: string,\n key: string,\n previous: Previous,\n source: string,\n toError: ToError,\n): void {\n const old: unknown = before === null ? null : parseYaml(before);\n // Every old key as it was, the key set, and the previous key set, removed\n // or left alone as `previous` says.\n const expected = Object.fromEntries(\n Object.entries({\n ...(isMapping(old) ? old : {}),\n [ENCRYPTION_KEY_FIELD]: key,\n ...(typeof previous === \"string\" ? { [ENCRYPTION_KEY_PREVIOUS_FIELD]: previous } : {}),\n }).filter(([name]) => previous !== null || name !== ENCRYPTION_KEY_PREVIOUS_FIELD),\n );\n const reread: unknown = parseYaml(after);\n if (!isMapping(reread) || !isDeepStrictEqual(reread, expected)) {\n throw toError(\n `Could not write ${ENCRYPTION_KEY_FIELD} to ${source}; add the key by hand.`,\n );\n }\n}\n\n/**\n * Set the top-level `encryptionKey:` and write the file atomically.\n *\n * `file` is the config to write into: the running tool's discovered config,\n * or `findFamilyConfigFile`'s for `manni key`. With `null`, the key goes to\n * the family file at the git root (else `cwd`), created holding only the key\n * when there is none. A single-tool file (legacy, or an explicit `-c` file\n * read whole as one tool's section) is refused. `dryRun` does everything but\n * the write, so a caller can name the target before asking about it.\n *\n * `previous` is for `manni key rotate` alone: a string writes it as\n * `encryptionKeyPrevious:` in the same atomic write as the key, `null`\n * removes it, and omitted leaves the file's own. Never echoed either.\n */\nexport async function writeEncryptionKey(opts: {\n file: ConfigFile | null;\n key: string;\n cwd: string;\n toError: ToError;\n dryRun?: boolean;\n previous?: string | null;\n}): Promise<{ path: string; source: string; created: boolean }> {\n const { file, key, toError, previous } = opts;\n if (!isValidEncryptionKey(key)) {\n throw toError(\n `The ${ENCRYPTION_KEY_FIELD} must be at least 32 hex or base64url characters.`,\n );\n }\n if (typeof previous === \"string\" && !isValidEncryptionKey(previous)) {\n throw toError(\n `The ${ENCRYPTION_KEY_PREVIOUS_FIELD} must be at least 32 hex or base64url characters.`,\n );\n }\n const target =\n file === null ? await defaultTarget(opts.cwd) : await fileTarget(file, toError);\n const text =\n target.text === null\n ? stringify({\n [ENCRYPTION_KEY_FIELD]: key,\n ...(typeof previous === \"string\" ? { [ENCRYPTION_KEY_PREVIOUS_FIELD]: previous } : {}),\n })\n : withKey(target.text, key, previous, target.source, toError);\n verify(target.text, text, key, previous, target.source, toError);\n if (opts.dryRun !== true) await writeTextAtomic(target.path, text);\n return { path: target.path, source: target.source, created: target.text === null };\n}\n\n/**\n * Whether git ignores `path`, which need not exist yet: `git check-ignore -q`.\n * `undefined` when git is absent or the path is not inside a work tree. A\n * tracked file is not ignored, whatever `.gitignore` says, so it is `false`.\n */\nexport function isIgnoredByGit(path: string): boolean | undefined {\n const result = spawnSync(\"git\", [\"check-ignore\", \"-q\", \"--\", basename(path)], {\n cwd: dirname(path),\n stdio: \"ignore\",\n windowsHide: true,\n });\n if (result.error !== undefined) return undefined;\n if (result.status === 0) return true;\n if (result.status === 1) return false;\n return undefined;\n}\n\n/** The warning for a key about to land in a file git would publish. */\nexport const committedKeyWarning = (source: string): string =>\n `${source} is not ignored by git: once committed, anyone who can read the repository can decrypt every encrypted value. Prefer MANNI_ENCRYPTION_KEY for a shared repository.`;\n","/**\n * An atomic text write for the shared layer: a temp file in the target's own\n * directory, then `rename`, so the file holds its old contents or its new\n * ones, never half of each.\n *\n * The metadata tool has a fuller one (`src/meta/core/write-file.ts`: byte\n * payloads, and an in-place fallback when Windows keeps a target locked). The\n * shared layer does not import a tool's module, so this is the small subset\n * the family config writer needs. When a later change moves meta's writer\n * here, this file is what it replaces.\n */\nimport { chmod, rename, rm, stat, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\n\n/** Windows returns these while an editor or scanner holds the target open. */\nconst LOCKED = new Set([\"EPERM\", \"EBUSY\", \"EACCES\"]);\nconst RENAME_ATTEMPTS = 3;\n\nfunction errorCode(err: unknown): string | undefined {\n return typeof err === \"object\" && err !== null && \"code\" in err\n ? String(err.code)\n : undefined;\n}\n\nconst wait = (ms: number): Promise<void> =>\n new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n\n/** Write `text` (UTF-8) to `path`, replacing it atomically. */\nexport async function writeTextAtomic(path: string, text: string): Promise<void> {\n const tmp = join(\n dirname(path),\n `.${basename(path)}.manni-${process.pid}-${Math.random().toString(36).slice(2, 8)}.tmp`,\n );\n try {\n await writeFile(tmp, text, \"utf8\");\n // Keep the target's permissions; a missing target keeps the default mode.\n try {\n const { mode } = await stat(path);\n await chmod(tmp, mode);\n } catch {\n // Creating the file, or its mode is unreadable: keep the default.\n }\n for (let attempt = 1; ; attempt++) {\n try {\n await rename(tmp, path);\n return;\n } catch (err) {\n const code = errorCode(err);\n if (code === undefined || !LOCKED.has(code) || attempt >= RENAME_ATTEMPTS) {\n throw err;\n }\n await wait(attempt * 50);\n }\n }\n } finally {\n await rm(tmp, { force: true });\n }\n}\n","/**\n * `x-manni-encrypt` (proposal 0045): what meta does with a property whose\n * schema says the page must hold its value encrypted.\n *\n * The keyword itself is registered on every Ajv meta builds (validator.ts),\n * where it records the instance pointers it is evaluated at. Ajv's own\n * resolution is the walker, so a mark counts wherever the validator evaluates\n * it: through `$ref`, `allOf` and a referenced built-in, and inside `anyOf`,\n * `oneOf` and `if`/`then` branches Ajv actually takes. This module is what\n * happens next, and is the same for every command:\n *\n * - a marked value the page holds in plain text is a finding\n * (`encrypted:plain`), unless an external-metadata manifest supplied it;\n * - an encrypted one that decrypts under the key is validated as its\n * plaintext, on a copy, and no finding may print that plaintext;\n * - one that does not decrypt is a finding (`encrypted:unreadable`);\n * - with no key, findings at or under it are dropped and counted, and the run\n * says so once.\n *\n * The plaintext never leaves this module except as the copy validation reads\n * and the value a writer is about to encrypt.\n */\nimport type { DerivedField } from \"./derive/types.js\";\nimport type { ConfigFile } from \"../../shared/config-file.js\";\nimport { decryptValue, isEncryptedValue } from \"../../shared/encryption.js\";\nimport {\n ENCRYPTION_KEY_ENV,\n resolveEncryptionKey,\n} from \"../../shared/encryption-key.js\";\nimport { escapePointerSegment } from \"../extractors/pointer.js\";\nimport { DocmetaError, type FieldError } from \"../types.js\";\nimport type { SourceLocation } from \"./external-metadata.js\";\n\n/** The schema keyword. `true` marks a property; `false` or absent does not. */\nexport const ENCRYPT_KEYWORD = \"x-manni-encrypt\";\n\n/**\n * The `schema` of a finding for a plain value in a marked property. Shaped\n * like `external:owned` so `classifyRef` passes it through as a built-in id,\n * and so its rule id is `encrypted:plain/encrypted`.\n */\nexport const ENCRYPTED_PLAIN_SCHEMA = \"encrypted:plain\";\n\n/** The `schema` of a finding for a value that does not decrypt. */\nexport const ENCRYPTED_UNREADABLE_SCHEMA = \"encrypted:unreadable\";\n\n/** The `keyword` both findings carry: no Ajv keyword produced them. */\nexport const ENCRYPTED_KEYWORD = \"encrypted\";\n\n/** What every report prints in place of a value it must not show. */\nexport const ENCRYPTED_PLACEHOLDER = \"(encrypted)\";\n\n/** The encryption context of a metadata value. */\nexport const META_CONTEXT = \"meta\";\n\n/**\n * The refusals encryption adds to a run: a key that will not resolve, a join\n * that cannot be matched, a write with no key. A class of its own so a command\n * that files a document's own errors per file (`fill`) can tell these apart:\n * they are about the run, and exit 2.\n */\nexport class EncryptionRefusal extends DocmetaError {}\n\nexport const plainMessage = (pointer: string): string =>\n `${pointer} holds a plain value; its schema marks it ${ENCRYPT_KEYWORD}.`;\n\nexport const unreadableMessage = (pointer: string): string =>\n `${pointer} does not decrypt under the current key: encrypted under another key, or edited by hand.`;\n\n/** The one run-level warning for values a run could not verify. */\nexport function unverifiedWarning(count: number): string {\n const what =\n count === 1\n ? \"1 encrypted value was not verified\"\n : `${count} encrypted values were not verified`;\n return `${what}: no encryption key is available. Set ${ENCRYPTION_KEY_ENV}, or run \\`manni key set\\`.`;\n}\n\n/** The key a run reads with, or `undefined`; resolved on first use. */\nexport type KeyGetter = () => string | undefined;\n\n/**\n * The run's key, resolved once and only when something needs it: a malformed\n * `MANNI_ENCRYPTION_KEY` is refused by the first run that meets a ciphertext,\n * not by every run in a repository that encrypts nothing.\n */\nexport function lazyKey(\n file: ConfigFile | undefined,\n env: NodeJS.ProcessEnv | undefined,\n): KeyGetter {\n let resolved: { key: string | undefined } | undefined;\n return () => {\n resolved ??= {\n key: resolveEncryptionKey({\n ...(env === undefined ? {} : { env }),\n file: file ?? null,\n toError: (m) => new EncryptionRefusal(m),\n }).key,\n };\n return resolved.key;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Pointers\n// ---------------------------------------------------------------------------\n\n/** The `/key` pointer of a top-level key. */\nexport function pointerOf(key: string): string {\n return `/${escapePointerSegment(key)}`;\n}\n\nfunction segments(pointer: string): string[] {\n if (pointer === \"\") return [];\n return pointer\n .slice(1)\n .split(\"/\")\n .map((s) => s.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n}\n\n/** The top-level key a one-segment pointer names; `undefined` otherwise. */\nexport function topLevelKeyOf(pointer: string): string | undefined {\n const parts = segments(pointer);\n return parts.length === 1 ? parts[0] : undefined;\n}\n\n/** Whether `pointer` is `ancestor` or somewhere beneath it. */\nexport function isAtOrUnder(pointer: string, ancestor: string): boolean {\n return (\n pointer === ancestor || ancestor === \"\" || pointer.startsWith(`${ancestor}/`)\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** The value at `pointer`, or `undefined` when there is none. */\nexport function valueAt(data: unknown, pointer: string): unknown {\n let node: unknown = data;\n for (const seg of segments(pointer)) {\n if (Array.isArray(node)) {\n const items: unknown[] = node;\n node = /^\\d+$/.test(seg) ? items[Number(seg)] : undefined;\n } else if (isRecord(node)) {\n node = Object.hasOwn(node, seg) ? node[seg] : undefined;\n } else {\n return undefined;\n }\n }\n return node;\n}\n\n/**\n * `root` with the value at `pointer` replaced, copying only the containers on\n * the way down: the page's own object is never mutated. A pointer that does\n * not resolve leaves `root` as it was.\n */\nexport function withValueAt<T>(root: T, pointer: string, value: unknown): T {\n const parts = segments(pointer);\n const set = (node: unknown, i: number): unknown => {\n const seg = parts[i];\n if (seg === undefined) return value;\n if (Array.isArray(node)) {\n const items: unknown[] = [...(node as unknown[])];\n if (!/^\\d+$/.test(seg) || Number(seg) >= items.length) return node;\n items[Number(seg)] = set(items[Number(seg)], i + 1);\n return items;\n }\n if (isRecord(node) && Object.hasOwn(node, seg)) {\n return { ...node, [seg]: set(node[seg], i + 1) };\n }\n return node;\n };\n return set(root, 0) as T;\n}\n\n// ---------------------------------------------------------------------------\n// The view a run validates\n// ---------------------------------------------------------------------------\n\n/** What a document's marks came to, for one schema set. */\nexport interface EncryptionView {\n /** The document's data with every readable encrypted value decrypted. A copy. */\n data: Record<string, unknown>;\n /** Every marked pointer that holds a value, shallowest first. */\n marked: string[];\n /** Marked pointers holding a plain value the page itself wrote. */\n plain: string[];\n /** Marked pointers whose ciphertext decrypted under the key. */\n decrypted: string[];\n /** Marked pointers whose ciphertext does not decrypt under the key. */\n unreadable: string[];\n /** Marked pointers holding a ciphertext, with no key to read it. */\n unverified: string[];\n}\n\n/** What the view needs from a validator: its marks, per data and schema set. */\nexport interface MarkSource {\n markedPointers(\n data: Record<string, unknown>,\n refs: string[],\n ): Promise<ReadonlySet<string>>;\n}\n\n/**\n * Settling a view can uncover marks: a decrypted value may take an `if`\n * branch the ciphertext did not. Each round decrypts what the last one\n * found, and a real schema settles in two; the bound is a guard, not a limit\n * anyone meets.\n */\nconst MAX_ROUNDS = 8;\n\n/**\n * Collect a document's marks and decrypt what it can. `locate` answers for a\n * value an external-metadata manifest supplied. That exempts it from\n * `encrypted:plain` and nothing else: a manifest is private by construction,\n * so a plain value in one is not a leak, but a ciphertext in one is read,\n * decrypted and reported under the same rules as one the page holds.\n */\nexport async function encryptionView(opts: {\n data: Record<string, unknown>;\n refs: string[];\n validator: MarkSource;\n key: KeyGetter;\n locate?: (pointer: string) => SourceLocation | undefined;\n}): Promise<EncryptionView> {\n const { data, refs, validator, key, locate } = opts;\n const view: EncryptionView = {\n data,\n marked: [],\n plain: [],\n decrypted: [],\n unreadable: [],\n unverified: [],\n };\n const seen = new Set<string>();\n const sealed: string[] = [];\n for (let round = 0; round < MAX_ROUNDS; round++) {\n const marks = await validator.markedPointers(view.data, refs);\n const fresh = [...marks]\n .filter((p) => !seen.has(p))\n .sort((a, b) => segments(a).length - segments(b).length);\n if (fresh.length === 0) break;\n for (const pointer of fresh) {\n seen.add(pointer);\n // Inside a ciphertext: the whole value is one token, so a mark on a\n // part of it is covered by the one on the whole.\n if (sealed.some((s) => isAtOrUnder(pointer, s))) continue;\n const value = valueAt(data, pointer);\n if (value === undefined) continue;\n view.marked.push(pointer);\n if (!isEncryptedValue(value)) {\n // A manifest is private by construction (0037), so a plain value it\n // supplied is not the leak `encrypted:plain` is about. That exemption\n // is about the *plain* case alone: a ciphertext a manifest supplied\n // is read, validated and reported exactly like one on the page.\n if (locate?.(pointer) === undefined) view.plain.push(pointer);\n continue;\n }\n sealed.push(pointer);\n const k = key();\n if (k === undefined) {\n view.unverified.push(pointer);\n continue;\n }\n const opened = decryptValue(value, k, META_CONTEXT);\n if (!opened.ok) {\n view.unreadable.push(pointer);\n continue;\n }\n view.decrypted.push(pointer);\n view.data = withValueAt(view.data, pointer, opened.value);\n }\n }\n return view;\n}\n\n/**\n * Keywords whose Ajv message or `params` name a part of the value itself — a\n * property name of an object — rather than something the schema says.\n */\nconst VALUE_NAMING = new Map<string, string>([\n [\"additionalProperties\", \"must NOT have additional properties\"],\n [\"unevaluatedProperties\", \"must NOT have unevaluated properties\"],\n [\"propertyNames\", \"property name must be valid\"],\n]);\n\ninterface Positions {\n lineFor(this: void, pointer: string): number | undefined;\n colFor?(this: void, pointer: string): number | undefined;\n}\n\n/** Where a merged value lives, when a manifest supplied it (0037). */\ntype Locator = (pointer: string) => SourceLocation | undefined;\n\n/**\n * The place a finding points at: the manifest entry's own line when a\n * manifest supplied the value, and the document's own position otherwise.\n * The same order `toFieldError` uses, so an encryption finding and a schema\n * finding on one pointer name the same place.\n */\nfunction at(\n pointer: string,\n pos: Positions,\n locate?: Locator,\n): { file?: string; line?: number; col?: number } {\n const located = locate?.(pointer);\n if (located) {\n return {\n file: located.file,\n ...(located.line != null ? { line: located.line } : {}),\n ...(located.col != null ? { col: located.col } : {}),\n };\n }\n const line = pos.lineFor(pointer);\n const col = pos.colFor?.(pointer);\n return { ...(line != null ? { line } : {}), ...(col != null ? { col } : {}) };\n}\n\n/**\n * Validation findings as a report may show them. Dropped at or under a value\n * that could not be read; at or under a decrypted value, moved to its pointer\n * and stripped of anything naming the plaintext, so neither the message, the\n * subject, nor the path of a nested key says more than the page did.\n */\nexport function settleFindings(\n errors: readonly FieldError[],\n view: EncryptionView,\n pos: Positions,\n locate?: Locator,\n): FieldError[] {\n const hidden = [...view.unreadable, ...view.unverified];\n const out: FieldError[] = [];\n for (const e of errors) {\n if (hidden.some((p) => isAtOrUnder(e.instancePath, p))) continue;\n const inside = view.decrypted.find((p) => isAtOrUnder(e.instancePath, p));\n const generic = VALUE_NAMING.get(e.keyword);\n if (inside === undefined || (e.instancePath === inside && generic === undefined)) {\n out.push(e);\n continue;\n }\n const { subject, file: _file, line: _line, col: _col, ...rest } = e;\n void _file;\n void _line;\n void _col;\n out.push({\n ...rest,\n instancePath: inside,\n message: generic ?? e.message,\n ...(generic === undefined && subject !== undefined ? { subject } : {}),\n ...at(inside, pos, locate),\n });\n }\n return out;\n}\n\n/** The findings encryption itself raises for a view, in pointer order. */\nexport function encryptionFindings(\n view: EncryptionView,\n pos: Positions,\n locate?: Locator,\n): FieldError[] {\n return [\n ...view.plain.map((p) => ({ p, schema: ENCRYPTED_PLAIN_SCHEMA, message: plainMessage(p) })),\n ...view.unreadable.map((p) => ({\n p,\n schema: ENCRYPTED_UNREADABLE_SCHEMA,\n message: unreadableMessage(p),\n })),\n ].map(({ p, schema, message }) => ({\n schema,\n keyword: ENCRYPTED_KEYWORD,\n instancePath: p,\n message,\n ...at(p, pos, locate),\n }));\n}\n\n/**\n * A copy of `data` fit to leave the machine: every marked pointer, and any\n * ciphertext anywhere, reads `(encrypted)`. What `fill` sends a model (0017's\n * egress rule): neither the plaintext nor the ciphertext of a marked field.\n */\nexport function redactForModel(\n data: Record<string, unknown>,\n marked: Iterable<string>,\n): Record<string, unknown> {\n let out = data;\n for (const pointer of marked) {\n if (valueAt(out, pointer) !== undefined) {\n out = withValueAt(out, pointer, ENCRYPTED_PLACEHOLDER);\n }\n }\n const scrub = (node: unknown): unknown => {\n if (isEncryptedValue(node)) return ENCRYPTED_PLACEHOLDER;\n if (Array.isArray(node)) return (node as unknown[]).map(scrub);\n if (isRecord(node)) {\n return Object.fromEntries(Object.entries(node).map(([k, v]) => [k, scrub(v)]));\n }\n return node;\n };\n return scrub(out) as Record<string, unknown>;\n}\n\n/**\n * A compared managed field as a report may show it when its schema marks it\n * `x-manni-encrypt` (proposals 0040 and 0045): both values as `(encrypted)`,\n * the status and the evidence as they were. `derive` and the derived\n * comparison in `validate` both report through it.\n */\nexport function redactedDerived(f: DerivedField): DerivedField {\n return {\n ...f,\n ...(f.asserted !== undefined ? { asserted: ENCRYPTED_PLACEHOLDER } : {}),\n ...(f.derived !== null ? { derived: ENCRYPTED_PLACEHOLDER } : {}),\n };\n}\n","/**\n * `x-manni-location` (proposal 0047): where a schema would like a top-level\n * key's value stored, on the page or in external metadata.\n *\n * The keyword is registered on every Ajv meta builds (validator.ts), next to\n * `x-manni-encrypt`, and like it records where it was evaluated. Ajv's own\n * resolution is the walker, so a mark counts through `$ref`, `allOf` and a\n * referenced built-in, and inside the `anyOf`, `oneOf` and `if`/`then`\n * branches Ajv takes. Only top-level properties carry a preference; a nested\n * mark is accepted and ignored. `Validator.locationPreferences` is the one\n * question commands ask of it.\n *\n * One schema marking one key both ways is judged twice. Through `properties`,\n * `allOf` and local `$ref` alone, it is refused when the schema compiles.\n * Across conditional branches it is not an error: Ajv evaluates failing\n * branches too, so that schema gives the key no preference.\n */\n\n/** The schema keyword. */\nexport const LOCATION_KEYWORD = \"x-manni-location\";\n\n/** Where a top-level key prefers to live. */\nexport type FieldLocation = \"page\" | \"external\";\n\n/** A key's preferred location, and the schema ref whose mark decided it. */\nexport interface LocationPreference {\n location: FieldLocation;\n /** The ref, as given to `locationPreferences`, whose mark won. */\n schema: string;\n}\n\n/**\n * validate's two findings about a misplaced value, both warnings. Builtin-shaped\n * refs like `external:owned`, so the rule ids are `location:external/location`\n * and `location:page/location`.\n */\nexport const LOCATION_EXTERNAL_SCHEMA = \"location:external\";\nexport const LOCATION_PAGE_SCHEMA = \"location:page\";\n/** The `keyword` both findings carry. */\nexport const LOCATION_FINDING_KEYWORD = \"location\";\n\nexport function isFieldLocation(value: unknown): value is FieldLocation {\n return value === \"page\" || value === \"external\";\n}\n","/**\n * JSON Schema validation engine. Compiles and caches an Ajv validator per\n * schema reference, validates extracted metadata against each schema in a set,\n * and maps every violation to a {schema, instancePath, line, col} FieldError.\n */\nimport * as AjvDraft07Ns from \"ajv\";\nimport * as Ajv2019Ns from \"ajv/dist/2019.js\";\nimport * as Ajv2020Ns from \"ajv/dist/2020.js\";\nimport * as AjvDraft04Ns from \"ajv-draft-04\";\nimport * as addFormatsNs from \"ajv-formats\";\nimport { createRequire } from \"node:module\";\nimport type {\n DefinedError,\n ErrorObject,\n ValidateFunction,\n} from \"ajv/dist/2020.js\";\nimport { DocmetaError, type FieldError } from \"../types.js\";\nimport type { SourceLocation } from \"./external-metadata.js\";\nimport { escapePointerSegment } from \"../extractors/pointer.js\";\n\n// ajv ships its meta-schema refs as JSON. A static JSON import survives\n// bundling as a bare ESM import without the required `type: json` attribute, so\n// load it through `require` instead (ajv is an external dep at runtime).\nconst draft06MetaSchema = createRequire(import.meta.url)(\n \"ajv/dist/refs/json-schema-draft-06.json\",\n) as Record<string, unknown>;\n\n// ajv and ajv-formats are CommonJS with a default export; under NodeNext the\n// callable/constructable value lives on `.default`. Cast through the named\n// default types so tsc sees a constructor / callable. The per-dialect builds\n// expose the same shape, so we treat them all as the 2020 constructor type.\ntype AjvCtor = typeof import(\"ajv/dist/2020.js\").default;\nconst AjvDraft07 = AjvDraft07Ns.default as unknown as AjvCtor;\nconst Ajv2019 = Ajv2019Ns.default as unknown as AjvCtor;\nconst Ajv2020 = Ajv2020Ns.default as unknown as AjvCtor;\nconst AjvDraft04 = AjvDraft04Ns.default as unknown as AjvCtor;\nconst addFormats =\n addFormatsNs.default as unknown as typeof import(\"ajv-formats\").default;\nimport {\n loadSchema,\n publishedBuiltins,\n type LoadSchemaOptions,\n type RegisteredSchemas,\n} from \"./schema-registry.js\";\nimport { FILE_SCHEMA_KEY } from \"./resolve-schema.js\";\nimport { ENCRYPT_KEYWORD } from \"./encrypted.js\";\nimport {\n LOCATION_KEYWORD,\n isFieldLocation,\n type FieldLocation,\n type LocationPreference,\n} from \"./location.js\";\nimport { GRAPH_OUTPUT_KEYWORD } from \"./graph-output.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\n\ntype Dialect = \"2020\" | \"2019\" | \"draft7\" | \"draft4\";\n\n/**\n * Pick a JSON Schema dialect from a schema's own `$schema` meta-schema URI.\n * Remote schemas commonly target draft-07/draft-04, which the 2020 build can't\n * compile, so each dialect gets its own Ajv. A missing or unrecognized\n * `$schema` falls back to 2020 (the dialect of the built-ins).\n */\nfunction dialectOf(schema: Record<string, unknown>): Dialect {\n const meta = typeof schema.$schema === \"string\" ? schema.$schema : \"\";\n if (meta.includes(\"2019-09\")) return \"2019\";\n // draft-06 shares the draft-07 build (its meta-schema is registered there).\n if (\n meta.includes(\"draft-07\") ||\n meta.includes(\"draft/7\") ||\n meta.includes(\"draft-06\") ||\n meta.includes(\"draft/6\")\n ) {\n return \"draft7\";\n }\n if (meta.includes(\"draft-04\") || meta.includes(\"draft/4\")) return \"draft4\";\n return \"2020\";\n}\n\nfunction buildAjv(\n dialect: Dialect,\n coerceTypes: false | \"array\" = false,\n): InstanceType<AjvCtor> {\n // strict: false so user-supplied schemas with lax metadata still compile.\n const opts = { allErrors: true, strict: false, coerceTypes } as const;\n const ajv =\n dialect === \"2019\"\n ? new Ajv2019(opts)\n : dialect === \"draft7\"\n ? new AjvDraft07(opts)\n : dialect === \"draft4\"\n ? new AjvDraft04(opts)\n : new Ajv2020(opts);\n addFormats(ajv);\n // draft-06 shares the draft-07 build; register its meta-schema so draft-06\n // schemas compile too rather than erroring on an unknown `$schema`.\n if (dialect === \"draft7\") ajv.addMetaSchema(draft06MetaSchema);\n registerEncryptKeyword(ajv);\n registerLocationKeyword(ajv);\n registerGraphOutputKeyword(ajv);\n registerBuiltins(ajv, dialect);\n return ajv;\n}\n\n/**\n * Where `x-manni-encrypt: true` records the instance pointers it is evaluated\n * at, while `markedPointers` is running. `undefined` the rest of the time, so\n * an ordinary validation pays one comparison per marked property.\n *\n * Module state is safe here because a compiled validator is synchronous: the\n * recorder is set, the one call runs to completion, and it is cleared, all in\n * one tick. `fill`'s worker pool interleaves only at its awaits, and there is\n * none inside that window.\n */\nlet markRecorder: Set<string> | undefined;\n\n/**\n * `x-manni-encrypt` (proposal 0045), on every Ajv meta builds. It never fails\n * a value: validation of a marked property is the rest of its schema, run on\n * the decrypted copy. What it does is say where it was evaluated, so Ajv's\n * own resolution — `$ref`, `allOf`, a referenced built-in, the `anyOf`,\n * `oneOf` and `if` branches it takes — decides where a mark counts.\n *\n * The boolean meta-schema is what refuses `\"x-manni-encrypt\": \"yes\"` at\n * compile time; `compileUncached` turns Ajv's wording into the one message\n * the plan ships.\n */\nfunction registerEncryptKeyword(ajv: InstanceType<AjvCtor>): void {\n ajv.addKeyword({\n keyword: ENCRYPT_KEYWORD,\n metaSchema: { type: \"boolean\" },\n errors: false,\n validate: (\n schema: unknown,\n _data: unknown,\n _parent?: unknown,\n cxt?: { instancePath: string },\n ): boolean => {\n if (schema === true && markRecorder !== undefined) {\n markRecorder.add(cxt?.instancePath ?? \"\");\n }\n return true;\n },\n });\n}\n\n/** Ajv's compile error for a non-boolean mark names the keyword. */\nfunction isMarkShapeError(err: unknown): boolean {\n return err instanceof Error && err.message.includes(`\"${ENCRYPT_KEYWORD}\"`);\n}\n\n/**\n * Where `x-manni-location` records what it says for each top-level key it is\n * evaluated at, while `locationPreferences` is running: key name to the set of\n * values seen, so one schema saying both is detectable. `undefined` the rest\n * of the time, for the same reason and with the same safety as\n * `markRecorder`.\n */\nlet locationRecorder: Map<string, Set<FieldLocation>> | undefined;\n\n/** A depth-1 instance pointer (`/owner`), as its unescaped key; else undefined. */\nfunction topLevelKey(instancePath: string): string | undefined {\n if (!instancePath.startsWith(\"/\") || instancePath.indexOf(\"/\", 1) !== -1) {\n return undefined;\n }\n return instancePath.slice(1).replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n}\n\n/**\n * `x-manni-location` (proposal 0047), on every Ajv meta builds. Like\n * `x-manni-encrypt`, it never fails a value; it says where it was evaluated,\n * so a mark counts wherever Ajv's resolution takes the validator. Only a mark\n * evaluated at a top-level property is recorded; a nested one is accepted and\n * ignored. The enum meta-schema refuses any other value at compile time, and\n * `compileUncached` turns Ajv's wording into the plan's message.\n */\nfunction registerLocationKeyword(ajv: InstanceType<AjvCtor>): void {\n ajv.addKeyword({\n keyword: LOCATION_KEYWORD,\n metaSchema: { type: \"string\", enum: [\"page\", \"external\"] },\n errors: false,\n validate: (\n schema: unknown,\n _data: unknown,\n _parent?: unknown,\n cxt?: { instancePath: string },\n ): boolean => {\n if (locationRecorder !== undefined && isFieldLocation(schema)) {\n const key = topLevelKey(cxt?.instancePath ?? \"\");\n if (key !== undefined) {\n const seen = locationRecorder.get(key);\n if (seen) seen.add(schema);\n else locationRecorder.set(key, new Set([schema]));\n }\n }\n return true;\n },\n });\n}\n\n/** Ajv's compile error for a mark outside the enum names the keyword. */\nfunction isLocationShapeError(err: unknown): boolean {\n return err instanceof Error && err.message.includes(`\"${LOCATION_KEYWORD}\"`);\n}\n\n/**\n * Where `x-manni-graph-output` records what it says for each top-level key it is\n * evaluated at, while `graphOutputPreferences` is running: key name to the set of\n * values seen, so one schema saying both is detectable. `undefined` the rest of\n * the time, for the same reason and with the same safety as `markRecorder`.\n */\nlet graphOutputRecorder: Map<string, Set<boolean>> | undefined;\n\n/**\n * `x-manni-graph-output` (proposal 0051 §5), on every Ajv meta builds. Like\n * `x-manni-location`, it never fails a value; it says where it was evaluated,\n * so a mark counts wherever Ajv's resolution takes the validator. Only a mark\n * evaluated at a top-level property is recorded; one nested inside `graph` is\n * accepted and ignored. The boolean meta-schema refuses any other value at\n * compile time, and `compileUncached` turns Ajv's wording into the plan's\n * message.\n */\nfunction registerGraphOutputKeyword(ajv: InstanceType<AjvCtor>): void {\n ajv.addKeyword({\n keyword: GRAPH_OUTPUT_KEYWORD,\n metaSchema: { type: \"boolean\" },\n errors: false,\n validate: (\n schema: unknown,\n _data: unknown,\n _parent?: unknown,\n cxt?: { instancePath: string },\n ): boolean => {\n if (graphOutputRecorder !== undefined && typeof schema === \"boolean\") {\n const key = topLevelKey(cxt?.instancePath ?? \"\");\n if (key !== undefined) {\n const seen = graphOutputRecorder.get(key);\n if (seen) seen.add(schema);\n else graphOutputRecorder.set(key, new Set([schema]));\n }\n }\n return true;\n },\n });\n}\n\n/** Ajv's compile error for a non-boolean mark names the keyword. */\nfunction isGraphOutputShapeError(err: unknown): boolean {\n return err instanceof Error && err.message.includes(`\"${GRAPH_OUTPUT_KEYWORD}\"`);\n}\n\n/** Does this schema mark its own top-level `$schema` property external? */\nfunction marksSchemaExternal(schema: Record<string, unknown>): boolean {\n const properties = schema[\"properties\"];\n if (typeof properties !== \"object\" || properties === null) return false;\n const own: unknown = (properties as Record<string, unknown>)[FILE_SCHEMA_KEY];\n if (typeof own !== \"object\" || own === null) return false;\n return (own as Record<string, unknown>)[LOCATION_KEYWORD] === \"external\";\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The first top-level key this schema gives two different values of the mark\n * `keyword` on paths every document takes; else undefined. `isMark` says\n * which values count, so a malformed one is left to the keyword's own check.\n *\n * Unconditional means the schema's own `properties`, its `allOf` entries, and\n * a local `$ref` reached from those, applied again inside a property's\n * subschema. `anyOf`, `oneOf`, `if`/`then`/`else` and `not` are conditional,\n * so marks that differ across them are not a contradiction. A remote `$ref`\n * is not chased, and neither is a local one inside an embedded `$id`, whose\n * `#` names another resource.\n */\nfunction definiteMarkConflict(\n root: Record<string, unknown>,\n keyword: string,\n isMark: (value: unknown) => boolean,\n): string | undefined {\n const marks = new Map<string, Set<unknown>>();\n /** The target of a `#/...` pointer from the root, if it resolves. */\n const localRef = (node: Record<string, unknown>, embedded: boolean): unknown => {\n const ref = node[\"$ref\"];\n if (embedded || typeof ref !== \"string\" || !ref.startsWith(\"#\")) return undefined;\n const pointer = ref.slice(1);\n if (pointer === \"\") return root;\n if (!pointer.startsWith(\"/\")) return undefined;\n let at: unknown = root;\n for (const raw of pointer.slice(1).split(\"/\")) {\n let segment: string;\n try {\n segment = decodeURIComponent(raw).replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n } catch {\n return undefined;\n }\n if (Array.isArray(at)) at = at[Number(segment)] as unknown;\n else if (isRecord(at)) at = at[segment];\n else return undefined;\n }\n return at;\n };\n const isEmbedded = (node: Record<string, unknown>, embedded: boolean): boolean =>\n embedded || (node !== root && typeof node[\"$id\"] === \"string\");\n const allOf = (node: Record<string, unknown>): unknown[] =>\n Array.isArray(node[\"allOf\"]) ? (node[\"allOf\"] as unknown[]) : [];\n\n const property = (key: string, node: unknown, embedded: boolean, visited: Set<unknown>): void => {\n if (!isRecord(node) || visited.has(node)) return;\n visited.add(node);\n const inner = isEmbedded(node, embedded);\n const mark = node[keyword];\n if (isMark(mark)) {\n const seen = marks.get(key);\n if (seen) seen.add(mark);\n else marks.set(key, new Set([mark]));\n }\n for (const entry of allOf(node)) property(key, entry, inner, visited);\n property(key, localRef(node, inner), inner, visited);\n };\n const object = (node: unknown, embedded: boolean, visited: Set<unknown>): void => {\n if (!isRecord(node) || visited.has(node)) return;\n visited.add(node);\n const inner = isEmbedded(node, embedded);\n const properties = node[\"properties\"];\n if (isRecord(properties)) {\n for (const [key, sub] of Object.entries(properties)) property(key, sub, inner, new Set());\n }\n for (const entry of allOf(node)) object(entry, inner, visited);\n object(localRef(node, inner), inner, visited);\n };\n object(root, false, new Set());\n for (const [key, seen] of marks) if (seen.size > 1) return key;\n return undefined;\n}\n\n/**\n * Make every built-in resolvable as a `$ref` target, under both of its names.\n *\n * Ajv is constructed with no `loadSchema`, so before this a user's schema could\n * not `$ref` a built-in by **any** route — not the published URL (nothing to\n * fetch it with) and not the docmeta id either, even though the schema was\n * bundled and would later be compiled into this very instance. Both failed with\n * \"can't resolve reference … from id #\", which reads like the published file is\n * broken. Proposal 0009 stress test 5.\n *\n * Three mechanics that are easy to get wrong:\n *\n * - **One call per built-in.** `addSchema(schema, url)` registers under the key\n * *and* under the schema's own `$id`, so the id form comes for free. Calling\n * it a second time under the id throws \"schema with key or id … already\n * exists\".\n * - **Meta-schema validation is off for these.** All the built-ins are\n * 2020-12, and the 2019/draft-07/draft-04 instances do not carry that\n * meta-schema — `addSchema` would throw `no schema with key or ref\n * \"https://json-schema.org/draft/2020-12/schema\"` and take out every Ajv but\n * one. These are docmeta's own files, covered by their own tests, so skipping\n * the check costs nothing. The flag is per call: a *user's* schema is still\n * validated normally.\n * - **All four dialects, not just 2020.** `dialectOf` picks the instance from\n * the *user's* `$schema`, so a draft-07 house schema extending OKF compiles in\n * the draft-07 Ajv and needs the built-ins registered there too.\n *\n * Registration is lazy — Ajv compiles a stored schema only when something\n * references it — so this costs a map insert per built-in, not fifteen compiles.\n *\n * Called from `buildAjv` rather than from `Validator`, deliberately:\n * `compileWithFormats` builds its own throwaway instance for `fill`'s proposal\n * envelope, which lifts subschemas out of the user's schemas and would\n * otherwise lose every `$ref` into a built-in.\n */\nfunction registerBuiltins(ajv: InstanceType<AjvCtor>, dialect: Dialect): void {\n for (const { id, url, legacyUrl, schema } of publishedBuiltins()) {\n ajv.addSchema(schema, url, undefined, false);\n // A user schema written before the rename `$ref`s the old URL. Same bytes,\n // same object; only the key differs.\n ajv.addSchema(schema, legacyUrl, undefined, false);\n // draft-04 predates `$id` — `ajv-draft-04` reads `id` instead — so the URL\n // key is the only registration the call above produces there, and the id\n // form has to be added explicitly. It does not throw as a duplicate for the\n // same reason: `$id` was never registered.\n if (dialect === \"draft4\") ajv.addSchema(schema, id, undefined, false);\n }\n}\n\n/**\n * Add a config's registered schemas (proposal 0070) to one Ajv, before\n * anything compiles there, as the built-ins are, so any schema can `$ref` one\n * by id. draft-04 reads `id` rather than `$id`, so there the id is the key.\n */\nfunction registerRegistered(\n ajv: InstanceType<AjvCtor>,\n dialect: Dialect,\n registered: RegisteredSchemas | undefined,\n): void {\n for (const { id, schema } of registered?.values() ?? []) {\n ajv.addSchema(schema, dialect === \"draft4\" ? id : undefined, undefined, false);\n }\n}\n\n/**\n * Compile an ad-hoc 2020-12 schema with docmeta's format support.\n *\n * `fill` needs this for the proposal envelope it builds around a document\n * schema's own property subschemas: those routinely carry `format: \"date-time\"`\n * / `\"uri\"`, and an Ajv without `ajv-formats` refuses to compile them outright.\n * A lifted subschema may `$ref` a registered schema, so the run's registered\n * schemas join this instance as they join the validator's.\n *\n * `coerce` turns on Ajv's `coerceTypes: \"array\"`, which rewrites a value of the\n * wrong JSON type into the declared one, in place, before any rule is judged:\n * `\"2\"` to `2`, `\"true\"` to `true`, a lone scalar to a one-item list. `fill`\n * checks each proposed value this way, on a copy. Off by default, because\n * everywhere else a value is judged as it stands.\n */\nexport function compileWithFormats(\n schema: Record<string, unknown>,\n registered?: RegisteredSchemas,\n options: { coerce?: boolean } = {},\n): ValidateFunction {\n const ajv = buildAjv(\"2020\", options.coerce === true ? \"array\" : false);\n registerRegistered(ajv, \"2020\", registered);\n return ajv.compile(schema);\n}\n\n/**\n * A bare Ajv carrying exactly the `addFormats` registration `buildAjv`\n * performs — the reference for what \"a format docmeta enforces\" means.\n * Shared by the two helpers below; built once, lazily.\n */\nlet formatRegistry: InstanceType<AjvCtor> | undefined;\nfunction formatsAjv(): InstanceType<AjvCtor> {\n if (!formatRegistry) {\n formatRegistry = new Ajv2020({ strict: false });\n addFormats(formatRegistry);\n }\n return formatRegistry;\n}\n\n/**\n * The format names docmeta's validators enforce on strings, derived from the\n * ajv-formats registration itself — never a hand-copied parallel list, so an\n * ajv-formats upgrade widens this set without anyone remembering it (proposal\n * 0028). Two exclusions, both because they do not constrain a string:\n * number-typed formats (`int32`, `float`, …) and always-pass placeholders\n * (`password`, `binary`, registered as `true`).\n */\nlet stringFormatsMemo: ReadonlySet<string> | undefined;\nexport function stringFormatNames(): ReadonlySet<string> {\n if (!stringFormatsMemo) {\n const names = new Set<string>();\n const registered: Record<string, unknown> = formatsAjv().formats;\n for (const [name, def] of Object.entries(registered)) {\n const enforcesStrings =\n def instanceof RegExp ||\n typeof def === \"function\" ||\n (typeof def === \"object\" &&\n def !== null &&\n ((def as { type?: string }).type === undefined ||\n (def as { type?: string }).type === \"string\"));\n if (enforcesStrings) names.add(name);\n }\n stringFormatsMemo = names;\n }\n return stringFormatsMemo;\n}\n\n/**\n * Does `value` satisfy the named format? Answered by compiling\n * `{type: \"string\", format: name}` in the same registry — the exact machinery\n * `validate` enforces the format with, so there is no second opinion about\n * what a `date` is (0028's DEFAULT guard).\n */\nconst formatCheckers = new Map<string, ValidateFunction>();\nexport function validatesFormat(name: string, value: string): boolean {\n let fn = formatCheckers.get(name);\n if (!fn) {\n fn = formatsAjv().compile({ type: \"string\", format: name });\n formatCheckers.set(name, fn);\n }\n return fn(value);\n}\n\nexport class Validator {\n /**\n * How this validator's schemas are loaded: the disk cache location, its TTL,\n * and `--offline`. Held per instance rather than read from module state, so\n * two differently-configured validations in one process each get their own\n * settings.\n *\n * That is not full isolation, and the difference matters to a library\n * caller: `schema-registry` keeps a process-wide memo of fetched schemas, so\n * one validator's successful fetch is visible to another. `offline` is\n * excluded from that sharing on purpose — an offline validator will not be\n * served something this process pulled over the network — but the memo is\n * still shared, so a URL fetched once is not re-fetched per instance.\n */\n constructor(private readonly schemaOptions: LoadSchemaOptions = {}) {}\n\n private ajvByDialect = new Map<Dialect, InstanceType<AjvCtor>>();\n /**\n * Keyed on the in-flight *promise*, not the resolved validator. Caching the\n * result made this a check-then-act race: `fill` walks files through a worker\n * pool, so every worker missed the cache while the first `loadSchema` was\n * still pending and they all then compiled the same schema into the one\n * shared per-dialect Ajv. Ajv registers a schema's `$id` on the first compile\n * and rejects the second with \"schema with key or id ... already exists\",\n * which took down any multi-file run against an $id-bearing schema. Storing\n * the promise before the first await lets the losers await the one compile.\n */\n private cache = new Map<string, Promise<ValidateFunction>>();\n\n private ajvFor(dialect: Dialect): InstanceType<AjvCtor> {\n let ajv = this.ajvByDialect.get(dialect);\n if (!ajv) {\n ajv = buildAjv(dialect);\n registerRegistered(ajv, dialect, this.schemaOptions.registered);\n this.ajvByDialect.set(dialect, ajv);\n }\n return ajv;\n }\n\n /**\n * Synchronous by design: the `cache.set` has to happen in the same tick as\n * the miss, or a second caller can slip in before the entry exists.\n */\n private compile(ref: string): Promise<ValidateFunction> {\n const cached = this.cache.get(ref);\n if (cached) return cached;\n const pending = this.compileUncached(ref);\n this.cache.set(ref, pending);\n // A failed load or compile is not cached — a transient fetch failure must\n // stay retryable rather than poisoning the ref for this Validator's life.\n // The extra `catch` keeps the eviction off the returned promise's chain, so\n // it does not convert the rejection into a handled one for the caller.\n pending.catch(() => {\n if (this.cache.get(ref) === pending) this.cache.delete(ref);\n });\n return pending;\n }\n\n private async compileUncached(ref: string): Promise<ValidateFunction> {\n const schema = await loadSchema(ref, this.schemaOptions);\n // `$schema` is how a page names its schema; external metadata is found\n // through that schema, so the directive cannot live there.\n if (marksSchemaExternal(schema)) {\n throw new DocmetaError(\n `${ref}: \"${FILE_SCHEMA_KEY}\" cannot be stored in external metadata.`,\n );\n }\n const contradicted = definiteMarkConflict(schema, LOCATION_KEYWORD, isFieldLocation);\n if (contradicted !== undefined) {\n throw new DocmetaError(\n `${ref}: \"${LOCATION_KEYWORD}\" says both \"page\" and \"external\" for \"${contradicted}\".`,\n );\n }\n const graphContradicted = definiteMarkConflict(\n schema,\n GRAPH_OUTPUT_KEYWORD,\n (value) => typeof value === \"boolean\",\n );\n if (graphContradicted !== undefined) {\n throw new DocmetaError(\n `${ref}: \"${GRAPH_OUTPUT_KEYWORD}\" says both true and false for \"${graphContradicted}\".`,\n );\n }\n try {\n const ajv = this.ajvFor(dialectOf(schema));\n // This cache is keyed on the ref string, but Ajv's registry is keyed on\n // `$id` — so one schema named two ways (a published URL in a document's\n // `$schema`, a local path on the command line) misses the cache twice and\n // Ajv rejects the second compile as a duplicate id. Reuse the existing\n // registration instead. `$id` is the schema's identity as far as Ajv is\n // concerned, so if two refs claim the same one, sharing a validator is\n // the only reading available — the alternative is the hard error this\n // replaces.\n //\n // Reused only when the registration really is *this* object. Sharing on\n // the id alone was tolerable while a registration could only come from an\n // earlier compile in the same run. It stopped being tolerable when\n // `registerBuiltins` began pre-loading every built-in into every\n // instance: an id collision is no longer a race whose outcome depends on\n // ordering, it is certain, and the built-in always wins.\n //\n // What that would silently override is a vendored built-in the user then\n // edited — the workflow proposal 0009 actively encourages. `schemas\n // vendor` writes a copy carrying `$id: google:okf:0.1`, so a house rule\n // added to that copy would simply not apply, while the report went on\n // naming the local path.\n //\n // A different schema claiming a taken id is compiled on its own merits,\n // with the id dropped from a shallow copy: Ajv refuses a second schema\n // under one id, and the id is not what identifies a schema here anyway —\n // the *ref* is what reports name, what baselines fingerprint, and what\n // this cache is keyed on.\n const id = typeof schema[\"$id\"] === \"string\" ? schema[\"$id\"] : undefined;\n const registered = id != null ? ajv.getSchema(id) : undefined;\n if (registered) {\n if (registered.schema === schema) return registered;\n const { $id: _taken, ...anonymous } = schema;\n return ajv.compile(anonymous);\n }\n return ajv.compile(schema);\n } catch (err) {\n if (isMarkShapeError(err)) {\n throw new DocmetaError(\n `${ref}: \"${ENCRYPT_KEYWORD}\" must be true or false.`,\n );\n }\n if (isLocationShapeError(err)) {\n throw new DocmetaError(\n `${ref}: \"${LOCATION_KEYWORD}\" must be \"page\" or \"external\".`,\n );\n }\n if (isGraphOutputShapeError(err)) {\n throw new DocmetaError(\n `${ref}: \"${GRAPH_OUTPUT_KEYWORD}\" must be true or false.`,\n );\n }\n throw new DocmetaError(\n `Schema \"${ref}\" failed to compile: ${errorMessage(err)}`,\n );\n }\n }\n\n /**\n * The instance pointers of `data` that carry `x-manni-encrypt: true` under\n * any schema in `refs`, in the order the validator evaluated them.\n *\n * A first pass with the recording keyword, so a mark counts exactly where\n * validation would evaluate it. Only present values are marked: Ajv applies\n * a property's subschema to a property that exists. A branch Ajv does not\n * take (`then` behind a failing `if`, an `anyOf` branch after a passing\n * one) contributes nothing; a branch it takes contributes its marks\n * whether or not the branch passes, because a ciphertext routinely fails\n * the rest of its own subschema until it is decrypted.\n */\n async markedPointers(\n data: Record<string, unknown>,\n refs: string[],\n ): Promise<Set<string>> {\n const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;\n void _omit;\n const marks = new Set<string>();\n for (const ref of refs) {\n const fn = await this.compile(ref);\n markRecorder = marks;\n try {\n fn(subject);\n } finally {\n markRecorder = undefined;\n }\n }\n return marks;\n }\n\n /**\n * The location each top-level key of `data` prefers under `refs`: `page` or\n * `external`, and the ref whose `x-manni-location` mark decided it. A key no\n * schema marks has no entry.\n *\n * A first pass with the recording keyword, as `markedPointers` runs, so a\n * mark counts exactly where validation would evaluate it, and a nested mark\n * is ignored. Only present values are marked: Ajv applies a property's\n * subschema to a property that exists. A caller asking where a key it is\n * about to write belongs passes `data` that already holds the candidate\n * value. `$schema` is stripped first, as validation does.\n *\n * Refs are evaluated in order and a later ref's mark wins. A ref that says\n * both values for one key unconditionally is refused when it compiles; one\n * whose evaluated branches say both gives that key no preference.\n */\n async locationPreferences(\n data: Record<string, unknown>,\n refs: string[],\n ): Promise<Map<string, LocationPreference>> {\n const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;\n void _omit;\n const preferences = new Map<string, LocationPreference>();\n for (const ref of refs) {\n const fn = await this.compile(ref);\n const seen = new Map<string, Set<FieldLocation>>();\n locationRecorder = seen;\n try {\n fn(subject);\n } finally {\n locationRecorder = undefined;\n }\n for (const [key, locations] of seen) {\n const [location, ...others] = [...locations];\n // Both values seen at evaluation can only come from conditional\n // branches: `compileUncached` refuses the unconditional kind. With\n // `allErrors`, Ajv evaluates failing branches too, so neither value\n // is this ref's answer, and an earlier ref's stands.\n if (location === undefined || others.length > 0) continue;\n preferences.set(key, { location, schema: ref });\n }\n }\n return preferences;\n }\n\n /**\n * The top-level property names the schemas in `refs` claim: the keys of\n * each schema's own `properties`, each once. What a page's schema set\n * claims decides which merge-safe fields a `derive:` block with no `fields`\n * manages on it (proposal 0069). A property reached only through `allOf`,\n * `$ref` or a conditional is not counted, so a schema that should manage a\n * field names it in its root `properties`. A schema that fails to load or\n * compile throws, as it would for `validate`.\n */\n async claimedProperties(refs: readonly string[]): Promise<Set<string>> {\n const claimed = new Set<string>();\n for (const ref of refs) {\n // Read from the compiled schema, which the cache already holds, so a\n // schema the run would refuse is refused here too and none loads twice.\n const schema: unknown = (await this.compile(ref)).schema;\n if (typeof schema !== \"object\" || schema === null) continue;\n const properties: unknown = (schema as Record<string, unknown>)[\"properties\"];\n if (typeof properties !== \"object\" || properties === null || Array.isArray(properties)) continue;\n for (const key of Object.keys(properties)) claimed.add(key);\n }\n return claimed;\n }\n\n /**\n * Whether each top-level key of `data` belongs in a published graph under\n * `refs`, as its `x-manni-graph-output` mark says. A key no schema marks has no\n * entry, which the caller reads as `true`: absent means harvested.\n *\n * A first pass with the recording keyword, as `locationPreferences` runs, so\n * a mark counts exactly where validation would evaluate it, and a mark nested\n * inside `graph` is ignored. Only present values are marked: Ajv applies a\n * property's subschema to a property that exists. `$schema` is stripped\n * first, as validation does.\n *\n * Refs are evaluated in order and a later ref's mark wins, so a house schema\n * listed after a vocabulary refines it. A schema that says both on paths\n * every document takes is refused when it compiles. A ref whose conditional\n * branches say both `true` and `false` gives that key no preference: with\n * `allErrors`, Ajv evaluates failing branches too, so neither value is that\n * ref's answer and an earlier ref's stands.\n */\n async graphOutputPreferences(\n data: Record<string, unknown>,\n refs: string[],\n ): Promise<Map<string, boolean>> {\n const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;\n void _omit;\n const preferences = new Map<string, boolean>();\n for (const ref of refs) {\n const fn = await this.compile(ref);\n const seen = new Map<string, Set<boolean>>();\n graphOutputRecorder = seen;\n try {\n fn(subject);\n } finally {\n graphOutputRecorder = undefined;\n }\n for (const [key, values] of seen) {\n const [value, ...others] = [...values];\n if (value === undefined || others.length > 0) continue;\n preferences.set(key, value);\n }\n }\n return preferences;\n }\n\n /**\n * Validate `data` against every schema in `refs`. Returns all violations,\n * each tagged with the schema that produced it and a source line via\n * `lineFor`.\n *\n * `colFor` is optional and additive: this signature is public, so a fourth\n * *required* parameter — or a widened third one — would be a consumer break.\n * Callers with an extractor that supplies no column pass nothing and get the\n * previous behavior exactly.\n */\n async validate(\n data: Record<string, unknown>,\n refs: string[],\n lineFor: (pointer: string) => number | undefined,\n colFor?: (pointer: string) => number | undefined,\n /**\n * Where a merged value lives when it is not in the document (proposal\n * 0037): a manifest's file and line. Consulted before `lineFor`,\n * and additive in the way `colFor` was.\n */\n locate?: (pointer: string) => SourceLocation | undefined,\n ): Promise<FieldError[]> {\n // `$schema` is a docmeta directive, not part of the document's metadata —\n // strip it so schemas with additionalProperties:false don't flag it.\n const { [FILE_SCHEMA_KEY]: _omit, ...subject } = data;\n void _omit;\n\n const errors: FieldError[] = [];\n for (const ref of refs) {\n const fn = await this.compile(ref);\n const ok = fn(subject);\n if (ok) continue;\n for (const e of fn.errors ?? []) {\n errors.push(toFieldError(ref, e, lineFor, colFor, locate));\n }\n }\n return errors;\n }\n}\n\n/**\n * The stable identifier inside a violation's `params`, when there is one.\n *\n * Only keywords whose parameter names a *thing* qualify. `pattern` carries the\n * regex source and `enum`/`minLength`/`minimum` carry schema-authored values:\n * including those would change a violation's identity every time the schema\n * author edited the rule, which is exactly what a baseline must survive.\n *\n * `DefinedError` is Ajv's own discriminated union over `keyword`, so each arm\n * below is type-checked against the real `params` shape rather than duck-typed.\n */\nfunction subjectOf(e: DefinedError): string | undefined {\n switch (e.keyword) {\n case \"required\":\n return e.params.missingProperty;\n case \"additionalProperties\":\n return e.params.additionalProperty;\n case \"format\":\n return e.params.format;\n case \"type\":\n // A union schema (`\"type\": [\"string\", \"null\"]`) yields the comma-joined\n // `\"string,null\"` rather than a single name. That is stable, so it\n // fingerprints correctly — but anyone matching on `subject` downstream\n // should not assume one type per value.\n return e.params.type;\n default:\n return undefined;\n }\n}\n\nfunction toFieldError(\n schema: string,\n e: ErrorObject,\n lineFor: (pointer: string) => number | undefined,\n colFor?: (pointer: string) => number | undefined,\n locate?: (pointer: string) => SourceLocation | undefined,\n): FieldError {\n // Ajv's documented way to narrow: every error it raises for a built-in\n // vocabulary is a member of `DefinedError`, but `ValidateFunction.errors` is\n // typed as the open `ErrorObject` to leave room for custom keywords.\n const defined = e as DefinedError;\n const instancePath = e.instancePath;\n const subject = subjectOf(defined);\n // Both of these point `instancePath` at the *parent* object and name the\n // property in the message, so neither gets a column.\n //\n // The parent exists, so `colFor` answers happily — with the parent's column,\n // which is a different token from the one the message is about. For\n // `required` the property is not in the file at all; for\n // `additionalProperties` it is, but somewhere else entirely, and the parent\n // of a document's root is the root, whose recorded position is 1:1. So a\n // stray key on line 40 was annotated at line 1 column 1, a caret on the first\n // character of the file.\n //\n // A `line` on the parent is a useful \"look around here\". A caret is a claim\n // about one character, and for these two keywords it would be the wrong one.\n let message = e.message ?? \"is invalid\";\n let wantsColumn = true;\n if (defined.keyword === \"required\") {\n message = `must have required property '${defined.params.missingProperty}'`;\n wantsColumn = false;\n } else if (defined.keyword === \"additionalProperties\") {\n message = `must NOT have additional property '${defined.params.additionalProperty}'`;\n wantsColumn = false;\n }\n // A value a manifest supplied is not in the document, so `lineFor` has no\n // answer for it; `locate` does, down to the line of the deepest node the\n // pointer reaches. `additionalProperties` is the one keyword whose offending\n // value sits at a *child* of `instancePath`, so the child is asked first.\n // Inside a manifest value that is the stray key's own line rather than its\n // parent's. At the root it is the manifest line of a private key a public\n // schema refused, which is exactly the case a reader needs pointed at.\n const located =\n defined.keyword === \"additionalProperties\"\n ? (locate?.(\n `${instancePath}/${escapePointerSegment(defined.params.additionalProperty)}`,\n ) ?? locate?.(instancePath))\n : locate?.(instancePath);\n if (located) {\n return {\n schema,\n instancePath,\n message,\n keyword: e.keyword,\n ...(subject != null ? { subject } : {}),\n file: located.file,\n ...(located.line != null ? { line: located.line } : {}),\n ...(wantsColumn && located.col != null ? { col: located.col } : {}),\n };\n }\n const line = lineFor(instancePath);\n const col = wantsColumn ? colFor?.(instancePath) : undefined;\n return {\n schema,\n instancePath,\n message,\n keyword: e.keyword,\n ...(subject != null ? { subject } : {}),\n ...(line != null ? { line } : {}),\n ...(col != null ? { col } : {}),\n };\n}\n","/**\n * `x-manni-graph-output` (proposal 0051 §5): whether a top-level key belongs in a\n * published knowledge graph. graph harvests frontmatter into Turtle, JSON-LD,\n * iiRDS and a search index, all of which get published, and which fields belong\n * in that output is a property of the field rather than of the tool — so it is\n * recorded where the field is defined.\n *\n * The keyword is registered on every Ajv meta builds (validator.ts), next to\n * `x-manni-location`, and like it records where it was evaluated. Ajv's own\n * resolution is the walker, so a mark counts through `$ref`, `allOf` and a\n * referenced built-in, and inside the `anyOf`, `oneOf` and `if`/`then` branches\n * Ajv takes. Absent means `true`: every field is harvested unless a schema says\n * otherwise. Only a top-level property's mark counts; a mark nested inside `graph`\n * is accepted and ignored, as 0047 rule 2 ignores a nested `x-manni-location`.\n * `Validator.graphOutputPreferences` is the one question a tool asks of it.\n *\n * Why this is not `x-manni-location` (0051 stress test 3): the two answer\n * different questions. `x-manni-location` says where a field is *written* — in\n * the page or in a manifest — and says nothing about whether a delivered\n * artifact should carry it. A field can be `external` and still belong in the\n * graph (`authors` on a published page), or be page-local and not belong in it\n * at all. Overloading one mark would make `manni meta relocate` a publishing\n * decision.\n */\n\n/** The schema keyword. */\nexport const GRAPH_OUTPUT_KEYWORD = \"x-manni-graph-output\";\n","/**\n * What a page's schemas mark `x-manni-location: external`, for a manifest with\n * no `keys` (proposal 0068). Such a manifest owns those fields for that page,\n * so every command that merges one asks this first, through\n * `mergeWithMarks`.\n *\n * The page's schema set is resolved the way `validate` resolves it: by path,\n * collection and override, and by the page's own `$schema`, which a manifest\n * may never supply. So the set is known before anything is merged, and the\n * marks are read over the page with its keyless manifests' values in place.\n *\n * `pageClaims` reads the same set for what it claims rather than what it\n * marks: the top-level properties that decide which merge-safe fields a\n * `derive:` block with no `fields` manages on the page (proposal 0069).\n */\nimport { DocmetaError } from \"../types.js\";\nimport {\n loadConfig,\n schemaTrustRoot,\n type DocmetaConfig,\n type SchemaTrustRoot,\n} from \"./config.js\";\nimport type { PageMarks } from \"./external-metadata.js\";\nimport {\n collectSchemaPins,\n FILE_SCHEMA_KEY,\n rebaseConfigSchemaRefs,\n resolveSchemaSetWithSource,\n} from \"./resolve-schema.js\";\nimport { schemaLoadOptions } from \"./schema-registry.js\";\nimport { Validator } from \"./validator.js\";\n\nexport interface PageMarksOptions {\n /** The run's validator, or a way to build one on first use. */\n validator: Validator | (() => Validator);\n config: DocmetaConfig | null;\n /** The directory a page's own `$schema` is measured from. */\n cwd: string;\n trustRoot: SchemaTrustRoot;\n /** `-s/--schema`: the set every page is judged by, over config. */\n cliSchemas?: readonly string[];\n /**\n * The collections a page belongs to for its schema set, when the command\n * resolves sets over other collections than it merges manifests from.\n * Absent, the merge's own membership is used.\n */\n memberOf?: (label: string) => readonly string[];\n}\n\n/**\n * A `PageMarks` over the run's schemas. A page whose set cannot be resolved\n * or loaded gets `undefined`, so its keyless manifests own nothing for it\n * and the command reports the schema the way it always has.\n */\nexport function pageMarks(opts: PageMarksOptions): PageMarks {\n const validator = lazyValidator(opts);\n return async (label, probe, memberOf) => {\n const refs = pageRefs(opts, label, probe, memberOf);\n if (refs === undefined) return undefined;\n try {\n const preferences = await validator().locationPreferences({ ...probe }, refs);\n const marked = new Set<string>();\n for (const [key, p] of preferences) if (p.location === \"external\") marked.add(key);\n return marked;\n } catch (err) {\n if (err instanceof DocmetaError) return undefined;\n throw err;\n }\n };\n}\n\n/**\n * What a page's schemas claim, for the merge-safe default (proposal 0069):\n * the top-level property names of every schema in its set, resolved the way\n * `pageMarks` resolves it. `undefined` when the set cannot be resolved or\n * loaded, so the page claims nothing and the command reports the schema the\n * way it always has.\n */\nexport type PageClaims = (\n label: string,\n probe: Readonly<Record<string, unknown>>,\n memberOf: readonly string[],\n) => Promise<ReadonlySet<string> | undefined>;\n\nexport function pageClaims(opts: PageMarksOptions): PageClaims {\n const validator = lazyValidator(opts);\n return async (label, probe, memberOf) => {\n const refs = pageRefs(opts, label, probe, memberOf);\n if (refs === undefined) return undefined;\n try {\n return await validator().claimedProperties(refs);\n } catch (err) {\n if (err instanceof DocmetaError) return undefined;\n throw err;\n }\n };\n}\n\nfunction lazyValidator(opts: PageMarksOptions): () => Validator {\n let built: Validator | undefined;\n return () => (opts.validator instanceof Validator ? opts.validator : (built ??= opts.validator()));\n}\n\n/** The page's schema set, as `validate` resolves it. Throws when it cannot. */\nexport function pageSchemaSet(\n opts: PageMarksOptions,\n label: string,\n probe: Readonly<Record<string, unknown>>,\n memberOf: readonly string[],\n): string[] {\n return resolveSchemaSetWithSource({\n filePath: label,\n fileSchema: probe[FILE_SCHEMA_KEY],\n ...(opts.cliSchemas !== undefined ? { cliSchemas: [...opts.cliSchemas] } : {}),\n config: opts.config,\n memberOf: opts.memberOf?.(label) ?? memberOf,\n fileBase: opts.cwd,\n trustRoot: opts.trustRoot,\n }).schemas;\n}\n\n/** The page's schema set, or undefined when it cannot be resolved. */\nfunction pageRefs(\n opts: PageMarksOptions,\n label: string,\n probe: Readonly<Record<string, unknown>>,\n memberOf: readonly string[],\n): string[] | undefined {\n try {\n return pageSchemaSet(opts, label, probe, memberOf);\n } catch (err) {\n if (err instanceof DocmetaError) return undefined;\n throw err;\n }\n}\n\n/**\n * A validator for a command that validates nothing (`get`, `schemas`, `cite`),\n * built the way `validate` builds its own, for `pageMarks` to build on first\n * use.\n */\nexport function marksValidator(opts: {\n config: DocmetaConfig | null;\n cwd: string;\n configDir?: string;\n offline?: boolean;\n}): () => Validator {\n return () =>\n new Validator(\n schemaLoadOptions({\n root: opts.configDir ?? opts.cwd,\n fileBase: opts.cwd,\n ttlHours: opts.config?.schemaCache?.ttlHours,\n offline: opts.offline ?? opts.config?.offline,\n pins: collectSchemaPins(opts.config),\n registered: opts.config?.registered,\n }),\n );\n}\n\n/**\n * `pageMarks` for a sibling tool (`cite`, `key rotate`) that holds the family\n * file but not meta's config: meta's section is read from `configPath` and\n * rebased the way `resolveRunConfig` rebases it. `undefined` when the file has\n * none to read.\n */\nexport async function configMarks(configPath: string, cwd: string): Promise<PageMarks | undefined> {\n const loaded = await loadConfig(configPath, cwd);\n if (loaded === null) return undefined;\n const config = rebaseConfigSchemaRefs(loaded.config, loaded.dir, cwd);\n return pageMarks({\n validator: marksValidator({ config, cwd, configDir: loaded.dir }),\n config,\n cwd,\n trustRoot: schemaTrustRoot(cwd, loaded.dir),\n });\n}\n\n/**\n * Meta's section of a family file, rebased the way `resolveRunConfig` rebases\n * it, or `null` when the file has none. A sibling tool that writes a key meta\n * homes (`keyHome`) hands this to its `RelocationContext`, so the marks a\n * keyless manifest owns by are the ones `configMarks` reads.\n */\nexport async function metaSection(configPath: string, cwd: string): Promise<DocmetaConfig | null> {\n const loaded = await loadConfig(configPath, cwd);\n if (loaded === null) return null;\n return rebaseConfigSchemaRefs(loaded.config, loaded.dir, cwd);\n}\n\n/**\n * `configMarks` for a sibling tool that reads a family file every run (proposal\n * 0068), built once on first use. The page marks come from meta's section of\n * that file, or from meta's default set when the file has none for meta, or\n * when meta cannot read the file as its own. Without a file, the default set\n * decides.\n */\nexport function familyMarks(opts: {\n configPath: string | undefined;\n configDir: string;\n cwd: string;\n}): () => Promise<PageMarks> {\n let built: Promise<PageMarks> | undefined;\n const defaults = (): PageMarks =>\n pageMarks({\n validator: marksValidator({ config: null, cwd: opts.cwd, configDir: opts.configDir }),\n config: null,\n cwd: opts.cwd,\n trustRoot: schemaTrustRoot(opts.cwd, opts.configDir),\n });\n return () =>\n (built ??= (async () => {\n if (opts.configPath === undefined) return defaults();\n try {\n return (await configMarks(opts.configPath, opts.cwd)) ?? defaults();\n } catch (err) {\n if (err instanceof DocmetaError) return defaults();\n throw err;\n }\n })());\n}\n","/**\n * Relocation (proposal 0047): put a page's values where their schema's\n * `x-manni-location` mark and the config's manifests say they belong, and\n * give a value that prefers external metadata a manifest when it has none.\n *\n * `manni meta relocate` is this module with a CLI in front of it, and the\n * writers' and validate's offers run the same plan. Three steps, kept apart\n * so a caller can stop after any of them:\n *\n * - **Home selection** (`keyHome`, and inside `planRelocation`). A page in a\n * collection uses the first one it belongs to. With no collections, one\n * named `default` is created from the run's targets. With exactly one, the\n * target that names the page is appended to its `paths:`. With several and\n * the page in none, there is no home. The manifest is the collection's\n * first local `file:` entry, or `<collection>.metadata.yaml` beside the\n * config file. A URL manifest is never a home.\n * - **Planning** (`planRelocation`). Every move, every config edit and every\n * new file text is computed, and nothing is written. A change to a\n * manifest's `keys:` covers every member page of its collection, in both\n * directions, because a key a manifest owns and a page still carries is an\n * `external:owned` collision, and a key it stops owning is no longer read.\n * - **Applying** (`applyRelocation`). The texts are written, manifests first,\n * then the config, then the pages, and the caller's in-memory collections\n * are brought up to date, so a writer can put a value into the manifest the\n * plan just declared. A write that fails puts back the files already\n * written, so a run lands whole or not at all.\n *\n * A value never moves by being re-read. The page's own extraction and the\n * manifest's parsed value are what move, so an encrypted value goes as its\n * ciphertext, verbatim.\n */\nimport { isMissing } from \"../../shared/manifest-cas.js\";\nimport { access, readFile, stat, unlink } from \"node:fs/promises\";\nimport { basename, extname, isAbsolute, join, relative, resolve, sep } from \"node:path\";\nimport picomatch from \"picomatch\";\nimport {\n LineCounter,\n isMap,\n isNode,\n isScalar,\n isSeq,\n parse as parseYaml,\n parseDocument,\n type Document,\n} from \"yaml\";\nimport {\n isMember,\n ownsKey,\n parseCollections,\n type CollectionConfig,\n} from \"../../shared/collections.js\";\nimport { FAMILY_CONFIG_NAMES, type ConfigFile } from \"../../shared/config-file.js\";\nimport { findGitRoot } from \"../../shared/git-root.js\";\nimport { hasPagePlaceholder, pageManifestPath } from \"../../shared/page-manifest.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { decryptValue, isEncryptedValue } from \"../../shared/encryption.js\";\nimport { DocmetaError, type MetadataExtractor, type MetadataPatch } from \"../types.js\";\nimport { schemaTrustRoot, type DocmetaConfig, type RunConfig } from \"./config.js\";\nimport { memberOf } from \"./collections.js\";\nimport { EncryptionRefusal, META_CONTEXT, lazyKey } from \"./encrypted.js\";\nimport {\n PATH_JOIN,\n externalMetadataJoin,\n loadExternalMetadata,\n mergeWithMarks,\n outsideRefusal as perPageOutsideRefusal,\n type ExternalMetadataIndex,\n type ExternalMetadataValue,\n} from \"./external-metadata.js\";\nimport { removeManifestKey, spliceManifestValue } from \"./external-metadata-write.js\";\nimport { gitignoreOptions, resolveTargetSet, STDIN_TOKEN } from \"./load-files.js\";\nimport { FILE_SCHEMA_KEY, resolveElements, resolveSchemaSetWithSource } from \"./resolve-schema.js\";\nimport { classifyRef } from \"./schema-registry.js\";\nimport type { Validator } from \"./validator.js\";\nimport { writeFileAtomic } from \"./write-file.js\";\nimport { extractorByName, extractorForExtension } from \"../extractors/index.js\";\nimport { deepEqual } from \"../extractors/patch-util.js\";\nimport type { FieldLocation } from \"./location.js\";\nimport { pageMarks } from \"./page-marks.js\";\n\n// ---------------------------------------------------------------------------\n// The result: what `manni meta relocate` reports.\n// ---------------------------------------------------------------------------\n\n/** Why a value was moved: its schema's mark, or a manifest that already owns the key. */\nexport type RelocateMoveReason = \"preferred\" | \"owned\";\n\n/** Why a value stayed on the side it is on. */\nexport type RelocateStayReason =\n | \"no-home\"\n | \"read-only-format\"\n | \"no-join-value\"\n | \"values-differ\"\n | \"url-manifest\"\n | \"unreadable\";\n\n/** One value that moved, or would under `dryRun`. */\nexport type RelocateMove =\n | { key: string; to: \"page\"; from: string; reason: RelocateMoveReason }\n | {\n key: string;\n to: \"manifest\";\n manifest: string;\n /** 1-based line of the key in the manifest afterwards. Absent under `dryRun`. */\n line?: number;\n reason: RelocateMoveReason;\n };\n\n/** One value that stayed on the wrong side. */\nexport interface RelocateStay {\n key: string;\n reason: RelocateStayReason;\n /** The sentence the pretty reporter prints after `stays: `. Not part of the JSON shape. */\n detail?: string;\n}\n\nexport interface RelocateFileResult {\n /** The page, as the run labels it. */\n file: string;\n moved: RelocateMove[];\n stayed: RelocateStay[];\n /** A member page outside the paths the run named, reached through a `keys:` or `paths:` change. */\n beyond: boolean;\n}\n\nexport interface RelocateManifestResult {\n /** The manifest as the run reports it: relative to the run's base, or the URL. */\n file: string;\n collection: string;\n /** Its index in the collection's `externalMetadata:` before the run. */\n index: number;\n created: boolean;\n keysAdded: string[];\n keysRemoved: string[];\n /** The keys it owns afterwards. */\n keys: string[];\n /** Whether its last key went, so the config no longer declares it (R3). */\n undeclared: boolean;\n /** Pages beyond the named paths whose values a `keys:` change moves, or leaves. */\n beyond: number;\n}\n\nexport interface RelocateConfigResult {\n /** The config file relative to the working directory, or null when there is none and none was needed. */\n file: string | null;\n created: boolean;\n collectionsCreated: { name: string; paths: string[] }[];\n pathsAdded: { collection: string; path: string }[];\n}\n\nexport interface RelocateSummary {\n /** Pages with a value moved or stayed. */\n files: number;\n moved: number;\n stayed: number;\n manifestsCreated: number;\n}\n\nexport interface RelocateResult {\n dryRun: boolean;\n config: RelocateConfigResult;\n /** Every manifest the run creates, changes the keys of, or moves a value into or out of. */\n manifests: RelocateManifestResult[];\n files: RelocateFileResult[];\n summary: RelocateSummary;\n}\n\n/** Whether a relocate run exits 1: at least one value stayed on the wrong side. */\nexport function relocateFailed(result: Pick<RelocateResult, \"summary\">): boolean {\n return result.summary.stayed > 0;\n}\n\n// ---------------------------------------------------------------------------\n// The context: what a run already settled, handed over once.\n// ---------------------------------------------------------------------------\n\nexport interface RelocationContext {\n cwd: string;\n /** The directory the run's file labels are relative to. */\n base: string;\n /** `--no-config`: nothing may be written to a config, so no value has a home. */\n noConfig: boolean;\n config: DocmetaConfig | null;\n /** Set by `applyRelocation` when it creates the config file. */\n configDir?: string;\n configPath?: string;\n configFile?: ConfigFile;\n /**\n * The run's selected collections. `applyRelocation` edits these objects in\n * place and appends a created collection, so a caller holding the array\n * sees the new manifests.\n */\n collections: CollectionConfig[];\n /** Every declared collection, the same objects as `collections`, edited the same way. */\n declaredCollections: CollectionConfig[];\n /**\n * The run's targets as typed (positional paths and globs). A created\n * collection's `paths:`, and a path appended to the only collection, come\n * from here. `-` is never one.\n */\n targets: readonly string[];\n /** `-s/--schema`: the schema set every page is judged by, over config. */\n cliSchemas?: readonly string[];\n validator: Validator;\n /** `--as`: the extractor every page is read with. */\n as?: string;\n /** `--no-gitignore` (false), for the walk of a collection's member pages. */\n respectGitignore?: boolean;\n env?: NodeJS.ProcessEnv;\n onNotice?: (message: string) => void;\n}\n\n/** A context from what `resolveRunConfig` returned, plus the rest a plan needs. */\nexport function relocationContext(\n run: RunConfig,\n extras: {\n cwd: string;\n targets: readonly string[];\n validator: Validator;\n noConfig?: boolean;\n cliSchemas?: readonly string[];\n as?: string;\n respectGitignore?: boolean;\n env?: NodeJS.ProcessEnv;\n onNotice?: (message: string) => void;\n },\n): RelocationContext {\n return {\n cwd: extras.cwd,\n base: run.base,\n noConfig: extras.noConfig ?? false,\n config: run.config,\n ...(run.configDir !== undefined ? { configDir: run.configDir } : {}),\n ...(run.configPath !== undefined ? { configPath: run.configPath } : {}),\n ...(run.configFile !== undefined ? { configFile: run.configFile } : {}),\n collections: run.collections,\n declaredCollections: run.declaredCollections,\n targets: extras.targets.filter((t) => t !== STDIN_TOKEN),\n ...(extras.cliSchemas !== undefined ? { cliSchemas: extras.cliSchemas } : {}),\n validator: extras.validator,\n ...(extras.as !== undefined ? { as: extras.as } : {}),\n ...(extras.respectGitignore !== undefined ? { respectGitignore: extras.respectGitignore } : {}),\n ...(extras.env !== undefined ? { env: extras.env } : {}),\n ...(extras.onNotice !== undefined ? { onNotice: extras.onNotice } : {}),\n };\n}\n\n// ---------------------------------------------------------------------------\n// The model: the collections as the plan would leave them.\n// ---------------------------------------------------------------------------\n\n/** One manifest of the model, declared or about to be. */\ninterface ManifestRef {\n collection: string;\n index: number;\n /** `file:` as the config writes it. */\n written: string;\n url: boolean;\n /** Undefined for a URL, and for a `{page}` manifest, which names no one file. */\n absPath: string | undefined;\n /**\n * As the run reports it. A `{page}` manifest (proposal 0058) names one file\n * per page, so this is the pattern as written, and `Model.fileFor` answers\n * the file one page's values live in.\n */\n file: string;\n join: string;\n /** `file:` holds `{page}`: each page keeps its values in a manifest of its own. */\n perPage: boolean;\n created: boolean;\n /**\n * The manifest names no `keys` (proposal 0068): it owns what each page's\n * schemas mark external, so the plan never adds or removes a key of its.\n */\n implied: boolean;\n keysBefore: string[];\n keysAdded: string[];\n keysRemoved: string[];\n}\n\nconst toPosix = (p: string): string => p.split(sep).join(\"/\");\n\nfunction reported(abs: string, base: string): string {\n const rel = relative(base, abs);\n return rel === \"\" ? \".\" : toPosix(rel);\n}\n\n/** The config file relative to the working directory, as every message names it. */\nfunction configSource(path: string, cwd: string): string {\n return toPosix(relative(cwd, path)) || basename(path);\n}\n\nfunction cloneCollection(c: CollectionConfig): CollectionConfig {\n return {\n ...c,\n paths: [...c.paths],\n exclude: [...c.exclude],\n externalMetadata: c.externalMetadata.map((m) => (m.keys === undefined ? { ...m } : { ...m, keys: [...m.keys] })),\n };\n}\n\n/** Where a page with no manifest for a key would get one. */\nexport type ProposedHome =\n | {\n kind: \"collection\";\n collection: string;\n /** The manifest the key would join, as the run reports it. */\n manifest: string;\n createsManifest: boolean;\n createsCollection: boolean;\n /** The run target appended to the collection's `paths:` (§3 case 3). */\n addsPath?: string;\n }\n | {\n kind: \"none\";\n /** `collections`: several are declared and the page is in none. `no-config`: `--no-config`. */\n reason: \"collections\" | \"no-config\";\n /** How many collections are declared. */\n collections: number;\n };\n\nclass Model {\n readonly collections: CollectionConfig[];\n readonly manifests: ManifestRef[] = [];\n readonly created: { name: string; paths: string[] }[] = [];\n readonly pathsAdded: { collection: string; path: string }[] = [];\n private targets: Promise<(string | undefined)[]> | undefined;\n\n constructor(\n private readonly ctx: RelocationContext,\n readonly configDir: string,\n ) {\n this.collections = ctx.declaredCollections.map(cloneCollection);\n for (const c of this.collections) {\n c.externalMetadata.forEach((m, index) => {\n const url = classifyRef(m.file).kind === \"url\";\n const perPage = !url && hasPagePlaceholder(m.file);\n const absPath =\n url || perPage ? undefined : isAbsolute(m.file) ? m.file : resolve(configDir, m.file);\n this.manifests.push({\n collection: c.name,\n index,\n written: m.file,\n url,\n absPath,\n file: absPath === undefined ? m.file : reported(absPath, ctx.base),\n join: externalMetadataJoin(m),\n perPage,\n created: false,\n implied: m.keys === undefined,\n keysBefore: [...(m.keys ?? [])],\n keysAdded: [],\n keysRemoved: [],\n });\n });\n }\n }\n\n members(label: string): string[] {\n return memberOf(this.collections, this.configDir, this.ctx.base, label);\n }\n\n /** The run's targets as `paths:` entries, in target order; resolved once, on first use. */\n private targetPaths(): Promise<(string | undefined)[]> {\n this.targets ??= Promise.all(this.ctx.targets.map((t) => collectionPath(t, this.ctx.cwd, this.configDir)));\n return this.targets;\n }\n\n manifestsOf(collection: string): ManifestRef[] {\n return this.manifests.filter((m) => m.collection === collection);\n }\n\n /**\n * The one file `m` keeps a page's values in, and how the run reports it:\n * the page's own for a `{page}` manifest (proposal 0058), the declared file\n * for any other. `abs` is undefined only for a URL manifest.\n */\n fileFor(m: ManifestRef, pageAbs: string): { abs: string | undefined; file: string } {\n if (!m.perPage) return { abs: m.absPath, file: m.file };\n const resolved = pageManifestPath(m.written, this.configDir, pageAbs);\n if (\"outside\" in resolved) {\n // The loader refuses such a page first, whenever the run names it.\n const declared = this.ctx.declaredCollections.find((c) => c.name === m.collection)?.externalMetadata[m.index];\n throw new DocmetaError(\n perPageOutsideRefusal(declared ?? { file: m.written }, m.collection, resolved.pageRel),\n );\n }\n return { abs: resolved.abs, file: reported(resolved.abs, this.ctx.base) };\n }\n\n /**\n * The manifest of one of `members` that owns `key`, in declaration order.\n * `marked` is what the page's schemas mark external, which is what a\n * manifest with no `keys` owns (proposal 0068).\n */\n ownerOf(key: string, members: readonly string[], marked?: ReadonlySet<string>): ManifestRef | undefined {\n return this.manifests.find(\n (m) =>\n members.includes(m.collection) &&\n (m.implied ? this.impliedOwns(m, key, marked) : m.keysBefore.includes(key) || m.keysAdded.includes(key)),\n );\n }\n\n /** Does a keyless manifest own `key` for a page whose schemas mark `marked`? */\n impliedOwns(m: ManifestRef, key: string, marked: ReadonlySet<string> | undefined): boolean {\n const collection = this.collections.find((c) => c.name === m.collection);\n const declared = collection?.externalMetadata[m.index];\n return collection !== undefined && declared !== undefined && ownsKey(collection, declared, key, marked);\n }\n\n /** Does one of `members` declare a manifest with no `keys`? */\n hasImplied(members: readonly string[]): boolean {\n return this.manifests.some((m) => m.implied && members.includes(m.collection));\n }\n\n /** The page's collection to home a new key in, first by the run's selection. */\n private pick(members: readonly string[]): string | undefined {\n const selected = new Set(this.ctx.collections.map((c) => c.name));\n return members.find((m) => selected.has(m)) ?? members[0];\n }\n\n /**\n * §3's four cases. `commit` makes the choice part of the model (a created\n * collection, an appended path, a new manifest), which planning wants and a\n * lookup does not.\n */\n async home(\n label: string,\n commit: boolean,\n owns: (m: ManifestRef) => boolean = () => false,\n ): Promise<{ manifest: ManifestRef; proposed: ProposedHome } | { proposed: ProposedHome }> {\n if (this.ctx.noConfig) {\n return { proposed: { kind: \"none\", reason: \"no-config\", collections: this.collections.length } };\n }\n const members = this.members(label);\n let collection = this.pick(members);\n let createsCollection = false;\n let addsPath: string | undefined;\n if (collection === undefined) {\n const rel = this.relative(label);\n if (this.collections.length === 0) {\n const paths = dedupe(\n (await this.targetPaths()).flatMap((p) => (p === undefined ? [] : [p])),\n );\n if (rel === undefined || !paths.some((p) => isMember(bare(p), rel))) {\n return { proposed: { kind: \"none\", reason: \"collections\", collections: 0 } };\n }\n collection = \"default\";\n createsCollection = true;\n if (commit) {\n this.collections.push({ name: collection, paths, exclude: [], externalMetadata: [] });\n this.created.push({ name: collection, paths: [...paths] });\n }\n } else if (this.collections.length === 1 && this.collections[0] !== undefined) {\n const only = this.collections[0];\n const target = (await this.targetPaths()).find(\n (p) => p !== undefined && rel !== undefined && isMember(bare(p), rel),\n );\n if (target === undefined) {\n return { proposed: { kind: \"none\", reason: \"collections\", collections: 1 } };\n }\n collection = only.name;\n addsPath = target;\n if (commit) {\n only.paths.push(target);\n this.pathsAdded.push({ collection: only.name, path: target });\n }\n } else {\n return { proposed: { kind: \"none\", reason: \"collections\", collections: this.collections.length } };\n }\n }\n const name = collection;\n // A keyless manifest (proposal 0068) is a home only for what it owns: a\n // key cannot be added to a list it does not have.\n const local = this.manifestsOf(name).find((m) => !m.url && (!m.implied || owns(m)));\n const proposedOf = (m: { file: string; created: boolean }): ProposedHome => ({\n kind: \"collection\",\n collection: name,\n manifest: m.file,\n createsManifest: m.created,\n createsCollection,\n ...(addsPath !== undefined ? { addsPath } : {}),\n });\n if (local !== undefined) return { manifest: local, proposed: proposedOf(local) };\n\n const fileName = `${name}.metadata.yaml`;\n const absPath = join(this.configDir, fileName);\n const file = reported(absPath, this.ctx.base);\n if (!commit) return { proposed: proposedOf({ file, created: true }) };\n if (await exists(absPath, file)) {\n throw new DocmetaError(\n `${file} already exists and is not a manifest of collection ${name}; declare it under externalMetadata, or move it.`,\n );\n }\n const owner = this.collections.find((c) => c.name === name);\n const ref: ManifestRef = {\n collection: name,\n index: owner?.externalMetadata.length ?? 0,\n written: `./${fileName}`,\n url: false,\n absPath,\n file,\n join: PATH_JOIN,\n perPage: false,\n created: true,\n implied: false,\n keysBefore: [],\n keysAdded: [],\n keysRemoved: [],\n };\n owner?.externalMetadata.push({ file: ref.written, keys: [] });\n this.manifests.push(ref);\n return { manifest: ref, proposed: proposedOf(ref) };\n }\n\n addKey(m: ManifestRef, key: string): void {\n if (m.implied || m.keysBefore.includes(key) || m.keysAdded.includes(key)) return;\n m.keysAdded.push(key);\n this.collections.find((c) => c.name === m.collection)?.externalMetadata[m.index]?.keys?.push(key);\n }\n\n removeKey(m: ManifestRef, key: string): void {\n if (!m.keysBefore.includes(key) || m.keysRemoved.includes(key)) return;\n m.keysRemoved.push(key);\n }\n\n /** The keys a manifest owns once the plan is applied. */\n finalKeys(m: ManifestRef): string[] {\n return [...m.keysBefore.filter((k) => !m.keysRemoved.includes(k)), ...m.keysAdded];\n }\n\n /** The collections as the config will declare them: removals applied, emptied manifests gone. */\n final(): CollectionConfig[] {\n return this.collections.map((c) => ({\n ...c,\n externalMetadata: c.externalMetadata.flatMap((em, index) => {\n const ref = this.manifests.find((m) => m.collection === c.name && m.index === index);\n // A keyless manifest (proposal 0068) is declared as it was.\n if (ref?.implied === true || (ref === undefined && em.keys === undefined)) return [em];\n const keys = ref === undefined ? (em.keys ?? []) : this.finalKeys(ref);\n return keys.length === 0 ? [] : [{ ...em, keys }];\n }),\n }));\n }\n\n /** A label relative to the config directory, posix; undefined outside it. */\n relative(label: string): string | undefined {\n if (label === \"<stdin>\") return undefined;\n const rel = toPosix(relative(this.configDir, resolve(this.ctx.base, label)));\n return isAbsolute(rel) || rel.startsWith(\"../\") ? undefined : rel;\n }\n}\n\nfunction dedupe<T>(xs: readonly T[]): T[] {\n return [...new Set(xs)];\n}\n\n/** A one-path collection, for asking whether a planned `paths:` entry covers a page. */\nfunction bare(path: string): CollectionConfig {\n return { name: \"\", paths: [path], exclude: [], externalMetadata: [] };\n}\n\n/**\n * A run target as a collection `paths:` entry, relative to the config\n * directory: `docs/` and a directory named without the slash become\n * `docs/**`, a glob and a file stay themselves. Undefined for stdin and for a\n * target outside the config directory, which no collection can hold.\n */\nasync function collectionPath(target: string, cwd: string, configDir: string): Promise<string | undefined> {\n if (target === STDIN_TOKEN) return undefined;\n const posix = target.replace(/\\\\/g, \"/\");\n const scanned = picomatch.scan(posix);\n if (scanned.isGlob) {\n // The glob's literal base resolves like a file target; the magic part rides along.\n const rel = toPosix(relative(configDir, resolve(cwd, scanned.base === \"\" ? \".\" : scanned.base)));\n if (isAbsolute(rel) || rel === \"..\" || rel.startsWith(\"../\")) return undefined;\n return rel === \"\" ? scanned.glob : `${rel}/${scanned.glob}`;\n }\n const abs = resolve(cwd, posix);\n const rel = toPosix(relative(configDir, abs));\n if (isAbsolute(rel) || rel.startsWith(\"..\")) return undefined;\n let directory = posix.endsWith(\"/\");\n if (!directory) {\n try {\n directory = (await stat(abs)).isDirectory();\n } catch {\n directory = false;\n }\n }\n if (!directory) return rel;\n return rel === \"\" ? \"**\" : `${rel}/**`;\n}\n\n/**\n * Whether `absPath` exists. Only a missing file is `false`: any other failure\n * to look is refused, rather than read as room to create the file.\n */\nasync function exists(absPath: string, file: string): Promise<boolean> {\n try {\n await access(absPath);\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") return false;\n throw new DocmetaError(`${file} could not be checked: ${errorMessage(err)}`);\n }\n}\n\n/** The directory a config is (or will be) in: the loaded one, else the git root, else cwd. */\nfunction plannedConfigDir(ctx: RelocationContext): string {\n return ctx.configDir ?? findGitRoot(ctx.cwd) ?? resolve(ctx.cwd);\n}\n\n// ---------------------------------------------------------------------------\n// Lookup: where a key lives, or where it would go.\n// ---------------------------------------------------------------------------\n\n/** Where key K of one page lives, or would. */\nexport type KeyHome =\n | {\n kind: \"manifest\";\n collection: string;\n /** As the run reports it. */\n file: string;\n absPath: string;\n /** `path`, or the page field the manifest joins on. */\n join: string;\n /** The page's entry: its path from the config directory, or its join value. Undefined when the page lacks the join field. */\n entry: string | undefined;\n /**\n * The manifest is the page's own, resolved from a `{page}` pattern\n * (proposal 0058). It may not exist yet: a writer holds it as empty\n * and creates it.\n */\n perPage: boolean;\n }\n | { kind: \"url\"; collection: string; file: string }\n | { kind: \"unowned\"; home: ProposedHome };\n\n/**\n * Where `key` of the page `label` lives in the context's current config: the\n * owning local manifest (with the page's entry in it), a URL manifest, or\n * nowhere, with the home §3 would choose. Reads no manifest and writes\n * nothing. `data` is the page's own metadata, for a field join; an encrypted\n * join value is decrypted with the run's key.\n */\nexport async function keyHome(\n ctx: RelocationContext,\n label: string,\n data: Readonly<Record<string, unknown>>,\n key: string,\n): Promise<KeyHome> {\n const model = new Model(ctx, plannedConfigDir(ctx));\n const members = model.members(label);\n // A keyless manifest (proposal 0068) owns the key when the page's schemas\n // mark it external, read with the key in place: Ajv evaluates a mark only\n // where the property is present.\n const marked = model.hasImplied(members)\n ? await marksOf(ctx)(\n label,\n Object.hasOwn(data, key) ? data : { ...data, [key]: null },\n memberOf(ctx.declaredCollections, ctx.configDir ?? ctx.cwd, ctx.base, label),\n )\n : undefined;\n const owner = model.ownerOf(key, members, marked);\n if (owner !== undefined) {\n // A `{page}` manifest (proposal 0058) resolves to the page's own file.\n const at = model.fileFor(owner, resolve(ctx.base, label));\n if (owner.url || at.abs === undefined) {\n return { kind: \"url\", collection: owner.collection, file: owner.file };\n }\n return {\n kind: \"manifest\",\n collection: owner.collection,\n file: at.file,\n absPath: at.abs,\n join: owner.join,\n entry: entryFor(owner, label, data, model.configDir, ctx.base, lazyKey(ctx.configFile, ctx.env)),\n perPage: owner.perPage,\n };\n }\n return { kind: \"unowned\", home: (await model.home(label, false)).proposed };\n}\n\n/** What a page's schemas mark external, over the context's schemas (proposal 0068). */\nfunction marksOf(ctx: RelocationContext): ReturnType<typeof pageMarks> {\n return pageMarks({\n validator: ctx.validator,\n config: ctx.config,\n cwd: ctx.cwd,\n trustRoot: schemaTrustRoot(ctx.cwd, ctx.configDir),\n ...(ctx.cliSchemas !== undefined ? { cliSchemas: ctx.cliSchemas } : {}),\n });\n}\n\n/** A page's entry in a manifest: its path from the config directory, or its join value. */\nfunction entryFor(\n m: ManifestRef,\n label: string,\n data: Readonly<Record<string, unknown>>,\n configDir: string,\n base: string,\n key: () => string | undefined,\n): string | undefined {\n if (m.join === PATH_JOIN) return toPosix(relative(configDir, resolve(base, label)));\n let raw = data[m.join];\n if (isEncryptedValue(raw)) {\n const k = key();\n if (k === undefined) {\n throw new EncryptionRefusal(\n `externalMetadata join field \"${m.join}\" is encrypted on these pages, and no encryption key is available to match them.`,\n );\n }\n const opened = decryptValue(raw, k, META_CONTEXT);\n if (!opened.ok) return undefined;\n raw = opened.value;\n }\n if (typeof raw === \"string\") return raw;\n if (typeof raw === \"number\" || typeof raw === \"boolean\") return String(raw);\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Planning.\n// ---------------------------------------------------------------------------\n\nexport interface RelocationRequest {\n /** The pages the run named, as labels relative to the context's base. */\n files: readonly string[];\n /** `--fields`: only these keys. Each must be marked, or manifest-owned, for some file. */\n fields?: readonly string[];\n /**\n * Keys a writer is about to set that need an external home for these\n * pages, whether or not the page holds them yet. Treated as preferring\n * external metadata; a key a manifest already owns needs nothing.\n */\n require?: ReadonlyMap<string, readonly string[]>;\n}\n\ntype Intent =\n | { kind: \"out\"; manifest: ManifestRef; reason: RelocateMoveReason; drop: boolean; entry: string }\n | { kind: \"in\"; manifest: ManifestRef; drop: boolean; entry: string; value: unknown }\n | {\n kind: \"stay\";\n reason: RelocateStayReason;\n detail: string;\n /** A manifest whose key removal this stay holds back. */\n blocks?: ManifestRef;\n /** The manifest the value was on its way out to. */\n toward?: ManifestRef;\n };\n\ninterface Page {\n label: string;\n absPath: string;\n format: string;\n content: string;\n elements: string[];\n extractor: MetadataExtractor;\n own: Record<string, unknown>;\n beyond: boolean;\n /** Why a page reached only beyond the named paths could not be read. Its `own` is empty. */\n unreadable?: string;\n intents: Map<string, Intent>;\n /** The page's text afterwards, when it changes. */\n text?: string;\n}\n\n/** One file the plan writes. */\nexport interface RelocationWrite {\n path: string;\n text: string;\n kind: \"manifest\" | \"config\" | \"page\";\n /**\n * The file's text on disk when the plan was made, or null when it did not\n * exist. Applying refuses a file that no longer matches, and a failed run\n * puts this text back.\n */\n before: string | null;\n}\n\n/** How `applyRelocation` changes the disk. Tests replace it; the default is atomic writes and `unlink`. */\nexport interface RelocationIo {\n write?: (path: string, text: string) => Promise<void>;\n remove?: (path: string) => Promise<void>;\n}\n\n/** A complete, validated plan: every text computed, nothing written. */\nexport interface RelocationPlan {\n /** The report, as a dry run shows it: no manifest lines. */\n result: RelocateResult;\n /** Every file to write, in write order. */\n writes: RelocationWrite[];\n /** Manifest lines per (file, key), for the applied report. */\n lines: ReadonlyMap<string, number>;\n /** The collections as the config declares them afterwards. */\n collections: CollectionConfig[];\n configDir: string;\n configPath: string;\n /** The per-collection offers the writers' and validate's prompts put. */\n offers: RelocationOffer[];\n /**\n * Pages whose external-preferring keys have no possible home, for the\n * writers' W2 line: several collections and the page in none, or\n * `--no-config`.\n */\n homeless: { file: string; keys: string[]; reason: \"collections\" | \"no-config\"; collections: number }[];\n}\n\n/**\n * The pages a `{page}` manifest (proposal 0058) is read for: the run's own,\n * and every member of a collection that declares one. A `keys:` change\n * reaches every member page, so a narrowed run still has to know what each\n * member's manifest holds. With no placeholder declared, nothing is walked.\n */\nasync function relocationPages(\n ctx: RelocationContext,\n request: RelocationRequest,\n): Promise<string[]> {\n const pages = new Set(request.files.map((label) => resolve(ctx.base, label)));\n const root = ctx.configDir ?? ctx.cwd;\n for (const collection of ctx.declaredCollections) {\n const perPage = collection.externalMetadata.some(\n (m) => classifyRef(m.file).kind !== \"url\" && hasPagePlaceholder(m.file),\n );\n if (!perPage) continue;\n const walked = await resolveTargetSet({\n inputs: [...collection.paths],\n cwd: root,\n allowEmpty: true,\n ...gitignoreOptions({\n ...(ctx.respectGitignore !== undefined ? { flag: ctx.respectGitignore } : {}),\n ...(ctx.config?.respectGitignore !== undefined ? { configured: ctx.config.respectGitignore } : {}),\n }),\n });\n for (const file of walked.files) pages.add(resolve(root, file));\n }\n return [...pages];\n}\n\n/**\n * Plan every move for `request.files` and the member pages a `keys:` change\n * reaches, with every new file text computed and read back. Writes nothing.\n *\n * Throws `DocmetaError` for a page that will not load, a schema that will not\n * resolve, a `--fields` name nothing marks or owns (U3), a manifest path that\n * exists undeclared (U6), a single-tool config file, and an edit that does\n * not read back as planned.\n */\nexport async function planRelocation(\n ctx: RelocationContext,\n request: RelocationRequest,\n): Promise<RelocationPlan> {\n const configDir = plannedConfigDir(ctx);\n const model = new Model(ctx, configDir);\n const encryptionKey = lazyKey(ctx.configFile, ctx.env);\n const marks = marksOf(ctx);\n const index = await loadExternalMetadata(ctx.declaredCollections, {\n configDir: ctx.configDir ?? ctx.cwd,\n base: ctx.base,\n offline: ctx.config?.offline ?? false,\n pages: await relocationPages(ctx, request),\n });\n const trustRoot = schemaTrustRoot(ctx.cwd, ctx.configDir);\n const forced = ctx.as !== undefined ? extractorByName(ctx.as) : undefined;\n const fields = request.fields === undefined ? undefined : new Set(request.fields);\n const wanted = (key: string): boolean => key !== FILE_SCHEMA_KEY && (fields === undefined || fields.has(key));\n const currentMembers = (label: string): string[] =>\n memberOf(ctx.declaredCollections, ctx.configDir ?? ctx.cwd, ctx.base, label);\n\n const pages = new Map<string, Page>();\n const runSet = new Set(request.files);\n const load = async (label: string, beyond: boolean): Promise<Page | undefined> => {\n const have = pages.get(label);\n if (have !== undefined) return have;\n // `--as` names how the run's own files are read; a sibling reached through a\n // keys: or paths: change is read by its extension, like any walk.\n const extractor = (beyond ? undefined : forced) ?? extractorForExtension(extname(label));\n if (extractor === undefined) {\n if (beyond) return undefined;\n throw new DocmetaError(`Unsupported file type \"${extname(label)}\" for \"${label}\". Use --as to override.`);\n }\n const absPath = resolve(ctx.base, label);\n const elements = resolveElements(label, ctx.config, currentMembers(label));\n let content = \"\";\n let own: Record<string, unknown> = {};\n let unreadable: string | undefined;\n // A named page that will not load refuses the run. A sibling is one page\n // among many the change reaches, so its values stay, with the reason.\n if (beyond) {\n try {\n content = await readFile(absPath, \"utf8\");\n own = extractor.extract(content, label, { elements }).data;\n } catch (err) {\n // The first line: a parser's excerpt of the source would break the report's one line per value.\n unreadable = (errorMessage(err).split(\"\\n\")[0] ?? \"\").replace(/:\\s*$/, \"\");\n }\n } else {\n content = await readFile(absPath, \"utf8\");\n try {\n own = extractor.extract(content, label, { elements }).data;\n } catch (err) {\n throw new DocmetaError(`${label}: ${errorMessage(err)}`);\n }\n }\n const page: Page = {\n label,\n absPath,\n format: extractor.name,\n content,\n elements,\n extractor,\n own,\n beyond,\n ...(unreadable !== undefined ? { unreadable } : {}),\n intents: new Map(),\n };\n pages.set(label, page);\n return page;\n };\n\n /** The value manifest `m` holds for `key` of `page` today. */\n const supplied = (m: ManifestRef, page: Page, key: string): ExternalMetadataValue | undefined => {\n if (m.created || index === null) return undefined;\n let sv: ExternalMetadataValue | undefined;\n if (m.join === PATH_JOIN) {\n sv = index.byPath.get(page.absPath)?.get(key);\n } else {\n const entry = entryFor(m, page.label, page.own, configDir, ctx.base, encryptionKey);\n sv = entry === undefined ? undefined : index.byField.get(m.join)?.get(entry)?.get(key);\n }\n // A `{page}` manifest's values carry the page's own file (proposal 0058).\n return sv !== undefined && sv.collection === m.collection && sv.file === model.fileFor(m, page.absPath).file\n ? sv\n : undefined;\n };\n\n const stay = (\n page: Page,\n key: string,\n reason: RelocateStayReason,\n detail: string,\n links: { blocks?: ManifestRef; toward?: ManifestRef } = {},\n ): void => {\n page.intents.set(key, { kind: \"stay\", reason, detail, ...links });\n };\n const urlDetail = (m: ManifestRef): string => `${m.file} is fetched and cannot be written`;\n const unreadableDetail = (page: Page): string => `this document could not be parsed: ${page.unreadable ?? \"\"}`;\n\n /** Out of the page, into `m`. */\n const planOut = (page: Page, m: ManifestRef, key: string, reason: RelocateMoveReason): void => {\n if (page.intents.has(key)) return;\n if (m.url) {\n stay(page, key, \"url-manifest\", urlDetail(m), { toward: m });\n return;\n }\n const entry = entryFor(m, page.label, page.own, configDir, ctx.base, encryptionKey);\n if (entry === undefined) {\n stay(page, key, \"no-join-value\", `this document has no ${m.join}, which ${m.file} joins on`, { toward: m });\n return;\n }\n const held = supplied(m, page, key);\n if (held !== undefined && !deepEqual(held.value, page.own[key])) {\n stay(page, key, \"values-differ\", `the page and ${held.file} hold different values`, { toward: m });\n return;\n }\n page.intents.set(key, { kind: \"out\", manifest: m, reason, drop: held !== undefined, entry });\n };\n\n /** Out of `m`, into the page. */\n const planIn = (page: Page, m: ManifestRef, key: string): void => {\n if (page.intents.has(key)) return;\n const held = supplied(m, page, key);\n if (held === undefined) return;\n const entry = entryFor(m, page.label, page.own, configDir, ctx.base, encryptionKey);\n /* c8 ignore next -- a supplied value was found through its entry. */\n if (entry === undefined) return;\n if (Object.hasOwn(page.own, key)) {\n if (!deepEqual(held.value, page.own[key])) {\n stay(page, key, \"values-differ\", `the page and ${held.file} hold different values`, { blocks: m });\n return;\n }\n page.intents.set(key, { kind: \"in\", manifest: m, drop: true, entry, value: held.value });\n return;\n }\n page.intents.set(key, { kind: \"in\", manifest: m, drop: false, entry, value: held.value });\n };\n\n // ---- The named pages: what their schemas and the config say ---------------\n const preferencesOf = new Map<string, Map<string, FieldLocation>>();\n const homeless = new Map<string, { keys: string[]; reason: \"collections\" | \"no-config\"; collections: number }>();\n const marked = new Set<string>();\n for (const label of request.files) {\n const page = await load(label, false);\n /* c8 ignore next -- a named page always has an extractor, or `load` threw. */\n if (page === undefined) continue;\n const members = currentMembers(label);\n const merged = await mergeWithMarks(\n label,\n { data: page.own, present: true, format: page.format, lineFor: () => undefined },\n index,\n members,\n ctx.base,\n { encryptionKey, marks },\n );\n const data = merged.extracted.data;\n const required = request.require?.get(label) ?? [];\n const resolved = resolveSchemaSetWithSource({\n filePath: label,\n fileSchema: data[FILE_SCHEMA_KEY],\n ...(ctx.cliSchemas !== undefined ? { cliSchemas: [...ctx.cliSchemas] } : {}),\n config: ctx.config,\n memberOf: members,\n fileBase: ctx.cwd,\n trustRoot,\n ...(ctx.onNotice !== undefined ? { onNotice: ctx.onNotice } : {}),\n });\n const probe: Record<string, unknown> = { ...data };\n for (const key of required) if (!(key in probe)) probe[key] = null;\n const prefs = new Map<string, FieldLocation>();\n /** What the schemas mark external, and so what a keyless manifest owns (0068). */\n const external = new Set<string>();\n for (const [key, p] of await ctx.validator.locationPreferences(probe, resolved.schemas)) {\n prefs.set(key, p.location);\n marked.add(key);\n if (p.location === \"external\") external.add(key);\n }\n for (const key of required) if (!prefs.has(key)) prefs.set(key, \"external\");\n preferencesOf.set(label, prefs);\n\n const planned = model.members(label);\n const joins = new Set(\n model.manifests.filter((m) => planned.includes(m.collection) && m.join !== PATH_JOIN).map((m) => m.join),\n );\n for (const m of model.manifests) {\n if (planned.includes(m.collection)) for (const k of [...m.keysBefore, ...m.keysAdded]) marked.add(k);\n }\n const keys = dedupe([...Object.keys(data), ...required]).filter(wanted);\n for (const key of keys) {\n if (joins.has(key)) continue;\n const pref = prefs.get(key);\n const inPage = Object.hasOwn(page.own, key);\n const owner = model.ownerOf(key, model.members(label), external);\n if (owner !== undefined) {\n if (pref === \"page\") {\n if (owner.url) {\n if (supplied(owner, page, key) !== undefined) stay(page, key, \"url-manifest\", urlDetail(owner));\n } else if (owner.keysBefore.includes(key)) {\n model.removeKey(owner, key);\n }\n } else if (inPage) {\n planOut(page, owner, key, pref === \"external\" ? \"preferred\" : \"owned\");\n }\n continue;\n }\n if (pref !== \"external\" || !(inPage || required.includes(key))) continue;\n const chosen = await model.home(label, true, (m) => model.impliedOwns(m, key, external));\n if (\"manifest\" in chosen) {\n // A keyless manifest owns the key already, so only this page's value moves.\n if (chosen.manifest.implied) {\n if (inPage) planOut(page, chosen.manifest, key, \"preferred\");\n continue;\n }\n model.addKey(chosen.manifest, key);\n continue;\n }\n if (chosen.proposed.kind !== \"none\") continue;\n if (inPage) {\n stay(\n page,\n key,\n \"no-home\",\n chosen.proposed.reason === \"no-config\"\n ? \"--no-config leaves this document no manifest\"\n : `this document is in none of the ${chosen.proposed.collections} collections, so it has no manifest`,\n );\n }\n const entry = homeless.get(label) ?? {\n keys: [],\n reason: chosen.proposed.reason,\n collections: chosen.proposed.collections,\n };\n entry.keys.push(key);\n homeless.set(label, entry);\n }\n }\n if (fields !== undefined) {\n for (const f of fields) {\n if (!marked.has(f) && !(request.require !== undefined && [...request.require.values()].some((ks) => ks.includes(f)))) {\n throw new DocmetaError(\n `\"${f}\" has no x-manni-location mark and no owning manifest for any file in this run.`,\n );\n }\n }\n }\n\n // ---- A key leaving keys: is headed for the page ---------------------------\n // A page planned before (or after) another page's mark removed the key would\n // otherwise send its copy to a manifest that no longer owns it. The move is\n // set aside, and put back if a page blocks the removal below.\n const suspended: { page: Page; manifest: ManifestRef; key: string; reason: RelocateMoveReason }[] = [];\n for (const page of pages.values()) {\n for (const [key, intent] of [...page.intents]) {\n const m = intent.kind === \"out\" ? intent.manifest : intent.kind === \"stay\" ? intent.toward : undefined;\n if (m === undefined || !m.keysRemoved.includes(key)) continue;\n page.intents.delete(key);\n const prefs = preferencesOf.get(page.label);\n suspended.push({\n page,\n manifest: m,\n key,\n reason: intent.kind === \"out\" ? intent.reason : prefs?.get(key) === \"external\" ? \"preferred\" : \"owned\",\n });\n }\n }\n\n // ---- A keys: or paths: change reaches every member page -------------------\n const grown = new Set(model.pathsAdded.map((p) => p.collection));\n const affected = new Set<string>(grown);\n for (const m of model.manifests) {\n if (m.keysAdded.length > 0 || m.keysRemoved.length > 0) affected.add(m.collection);\n }\n for (const name of affected) {\n const collection = model.collections.find((c) => c.name === name);\n /* c8 ignore next -- an affected collection is one of the model's. */\n if (collection === undefined) continue;\n const walked = await resolveTargetSet({\n inputs: [...collection.paths],\n cwd: configDir,\n allowEmpty: true,\n ...gitignoreOptions({\n ...(ctx.respectGitignore !== undefined ? { flag: ctx.respectGitignore } : {}),\n ...(ctx.config?.respectGitignore !== undefined ? { configured: ctx.config.respectGitignore } : {}),\n }),\n });\n const labels = dedupe([\n ...request.files,\n ...walked.files.map((f) => reported(resolve(configDir, f), ctx.base)),\n ]).filter((label) => model.members(label).includes(name));\n for (const label of labels) {\n const page = await load(label, !runSet.has(label));\n if (page === undefined) continue;\n const prefs = preferencesOf.get(label);\n // A page the paths: change brings in is covered for every key the\n // manifest owns, as a keys: change covers every page: --fields cannot\n // leave an owned key behind on it.\n const covered = grown.has(name) && !currentMembers(label).includes(name);\n for (const m of model.manifestsOf(name)) {\n const out = dedupe([\n ...m.keysAdded,\n ...(grown.has(name) ? m.keysBefore.filter((k) => !m.keysRemoved.includes(k)) : []),\n ]).filter((k) => (covered ? k !== FILE_SCHEMA_KEY : wanted(k)));\n if (page.unreadable !== undefined) {\n const detail = unreadableDetail(page);\n // The keys whose home this run changes for the page: added ones, and\n // every owned one when the page is newly covered.\n const changing = covered ? out : out.filter((k) => m.keysAdded.includes(k));\n for (const key of changing) if (!page.intents.has(key)) stay(page, key, \"unreadable\", detail);\n for (const key of m.keysRemoved) {\n // Whether the manifest sets the key for this page is known only\n // for a path join; a field join needs the page's own value.\n const held =\n m.join !== PATH_JOIN ||\n (!m.created && index?.byPath.get(page.absPath)?.get(key)?.file === model.fileFor(m, page.absPath).file);\n if (held && !page.intents.has(key)) stay(page, key, \"unreadable\", detail, { blocks: m });\n }\n continue;\n }\n for (const key of out) {\n if (!Object.hasOwn(page.own, key)) continue;\n const reason = m.keysAdded.includes(key) || prefs?.get(key) === \"external\" ? \"preferred\" : \"owned\";\n planOut(page, m, key, reason);\n }\n for (const key of m.keysRemoved) planIn(page, m, key);\n }\n }\n }\n\n // ---- Page texts, and removals a page blocks --------------------------------\n const orderedPages = (): Page[] => {\n const all = [...pages.values()];\n const run = all.filter((p) => !p.beyond).sort((a, b) => compare(a.label, b.label));\n const beyond = all.filter((p) => p.beyond).sort((a, b) => compare(a.label, b.label));\n return [...run, ...beyond];\n };\n // A worklist. Planning a page's text reads only that page's intents, so a\n // page whose intents did not change since its last planning would plan the\n // same text. The first pass plans every page; each later pass re-plans only\n // the pages the previous pass's unblocked removals touched, and looks among\n // them for new blocks. A block found earlier is settled: keysRemoved only\n // shrinks, so it cannot fire twice.\n let dirty = new Set<Page>(pages.values());\n while (dirty.size > 0) {\n // In the pages' own order, as every page was planned before.\n const pass = [...pages.values()].filter((p) => dirty.has(p));\n for (const page of pass) planPageText(page);\n const touched = new Set<Page>();\n for (const page of pass) {\n for (const [key, intent] of page.intents) {\n if (intent.kind !== \"stay\" || intent.blocks === undefined) continue;\n const m = intent.blocks;\n if (!m.keysRemoved.includes(key)) continue;\n m.keysRemoved.splice(m.keysRemoved.indexOf(key), 1);\n for (const other of pages.values()) {\n const i = other.intents.get(key);\n if (i?.kind === \"in\" && i.manifest === m) {\n other.intents.delete(key);\n touched.add(other);\n }\n }\n // The manifest keeps the key, so a copy set aside for the page goes to it after all.\n for (const s of suspended) {\n if (s.manifest === m && s.key === key) {\n planOut(s.page, m, key, s.reason);\n touched.add(s.page);\n }\n }\n }\n }\n dirty = touched;\n }\n\n // ---- Manifest texts --------------------------------------------------------\n const writes: RelocationWrite[] = [];\n const lines = new Map<string, number>();\n for (const m of model.manifests) {\n if (m.url) continue;\n const undeclared = !m.implied && model.finalKeys(m).length === 0 && !m.created;\n /**\n * The edits, by the file they land in. One file for a concrete manifest;\n * one per page for a `{page}` manifest (proposal 0058), so each page's\n * values go to, and come from, the page's own file.\n */\n type Edits = {\n file: string;\n outs: { page: string; entry: string; key: string; value: unknown; drop: boolean }[];\n ins: { entry: string; key: string }[];\n };\n const files = new Map<string, Edits>();\n const group = (at: { abs: string | undefined; file: string }): Edits | undefined => {\n /* c8 ignore next -- only a URL manifest has no path, and it was skipped. */\n if (at.abs === undefined) return undefined;\n const have = files.get(at.abs);\n if (have !== undefined) return have;\n const made: Edits = { file: at.file, outs: [], ins: [] };\n files.set(at.abs, made);\n return made;\n };\n // A created manifest is written even when nothing moves into it.\n if (m.created) group({ abs: m.absPath, file: m.file });\n for (const page of orderedPages()) {\n for (const [key, intent] of orderedIntents(page)) {\n if ((intent.kind === \"out\" || intent.kind === \"in\") && intent.manifest === m) {\n const into = group(model.fileFor(m, page.absPath));\n if (intent.kind === \"out\") {\n into?.outs.push({ page: page.label, entry: intent.entry, key, value: page.own[key], drop: intent.drop });\n } else {\n into?.ins.push({ entry: intent.entry, key });\n }\n }\n }\n }\n if (!undeclared) assertNoStrandedEntries(m, index, pages, configDir, (abs) => model.fileFor(m, abs).file);\n if (undeclared) continue;\n for (const [path, { file, outs, ins }] of files) {\n if (!m.created && outs.length === 0 && ins.length === 0) continue;\n // A created manifest's path does not exist: planning refuses one that\n // does (U6). A `{page}` manifest that does not exist yet reads as empty\n // and is created, `before: null`, like one.\n const disk = m.created ? null : await readManifestText(path, file, m.perPage);\n let text = disk ?? \"\";\n const before = text;\n const where = { join: m.join, file };\n for (const o of outs) {\n if (!o.drop) text = spliceManifestValue(text, { ...where, entry: o.entry, key: o.key, value: o.value }).text;\n }\n for (const i of ins) text = removeManifestKey(text, { ...where, entry: i.entry, key: i.key }).text;\n const found = keyLines(text, m.join);\n for (const o of outs) {\n const line = found.get(entryId(o.entry, m.join))?.get(o.key);\n if (line !== undefined) lines.set(lineId(o.page, file, o.key), line);\n }\n if (m.created || text !== before) {\n writes.push({ path, text, kind: \"manifest\", before: disk });\n }\n }\n }\n\n // ---- Config text ---------------------------------------------------------------\n const finalCollections = model.final();\n const needsConfig =\n model.created.length > 0 ||\n model.pathsAdded.length > 0 ||\n model.manifests.some((m) => m.created || m.keysAdded.length > 0 || m.keysRemoved.length > 0);\n const target = await configTarget(ctx, configDir);\n let configCreated = false;\n if (needsConfig) {\n if (ctx.configFile !== undefined && (ctx.configFile.kind === \"legacy\" || !ctx.configFile.wrapped)) {\n throw new DocmetaError(\n `${ctx.configFile.source} is a single-tool config file, which cannot hold collections:. Move its keys under meta: in ${FAMILY_CONFIG_NAMES[0] ?? \"manni.config.yaml\"}.`,\n );\n }\n const text = editConfig(target.text, model, configSource(target.path, ctx.cwd));\n verifyConfig(target.text, text, finalCollections, configSource(target.path, ctx.cwd));\n writes.push({ path: target.path, text, kind: \"config\", before: target.disk });\n configCreated = target.text === null;\n }\n\n for (const page of orderedPages()) {\n if (page.text !== undefined && page.text !== page.content) {\n writes.push({ path: page.absPath, text: page.text, kind: \"page\", before: page.content });\n }\n }\n\n const result = buildResult({\n model,\n pages: orderedPages(),\n dryRun: true,\n lines: new Map(),\n config: {\n file: needsConfig || ctx.configPath !== undefined ? configSource(target.path, ctx.cwd) : null,\n created: configCreated,\n collectionsCreated: model.created,\n pathsAdded: model.pathsAdded,\n },\n });\n return {\n result,\n writes,\n lines,\n collections: finalCollections,\n configDir,\n configPath: target.path,\n offers: buildOffers(model, orderedPages(), result, needsConfig ? configSource(target.path, ctx.cwd) : undefined),\n homeless: [...homeless].map(([file, h]) => ({ file, ...h })),\n };\n}\n\nconst compare = (a: string, b: string): number => (a < b ? -1 : a > b ? 1 : 0);\n\n/**\n * A page's intents in the page's own key order, then the rest (values coming\n * in from a manifest) as they were planned. Planning reaches a page's keys in\n * two passes, so insertion order alone would not follow the page.\n */\nfunction orderedIntents(page: Page): [string, Intent][] {\n const order = Object.keys(page.own);\n const rank = (key: string): number => {\n const i = order.indexOf(key);\n return i === -1 ? order.length : i;\n };\n return [...page.intents].sort(([a], [b]) => rank(a) - rank(b));\n}\n\n/**\n * The page's new text for its intents, read back. A format with no writer,\n * or a document its writer refuses, turns every intent that needs the page\n * written into a stay; one moving a value in blocks that key's removal.\n */\nfunction planPageText(page: Page): void {\n const patch: MetadataPatch = {};\n const deletions: string[] = [];\n for (const [key, intent] of page.intents) {\n if (intent.kind === \"out\") deletions.push(key);\n else if (intent.kind === \"in\" && !intent.drop) patch[key] = intent.value;\n }\n delete page.text;\n if (deletions.length === 0 && Object.keys(patch).length === 0) return;\n const refuse = (): void => {\n for (const [key, intent] of page.intents) {\n if (intent.kind === \"out\" || (intent.kind === \"in\" && !intent.drop)) {\n page.intents.set(key, {\n kind: \"stay\",\n reason: \"read-only-format\",\n detail: `the ${page.format} format cannot write this document's metadata`,\n ...(intent.kind === \"in\" ? { blocks: intent.manifest } : {}),\n });\n }\n }\n };\n const apply = page.extractor.apply;\n if (typeof apply !== \"function\") {\n refuse();\n return;\n }\n try {\n const next = apply(page.content, patch, {\n filePath: page.label,\n elements: page.elements,\n ...(deletions.length > 0 ? { deletions } : {}),\n });\n const after = page.extractor.extract(next, page.label, { elements: page.elements }).data;\n const wrote =\n deletions.every((k) => !Object.hasOwn(after, k)) &&\n Object.entries(patch).every(([k, v]) => deepEqual(after[k], v));\n if (!wrote) {\n refuse();\n return;\n }\n page.text = next;\n } catch (err) {\n if (!(err instanceof DocmetaError)) throw err;\n refuse();\n }\n}\n\n/**\n * A key leaving a manifest's `keys:` while an entry no member page matched\n * still sets it would make the manifest unloadable (\"sets a key it does not\n * own\"). Refused, naming the entry, rather than written.\n */\nfunction assertNoStrandedEntries(\n m: ManifestRef,\n index: ExternalMetadataIndex | null,\n pages: ReadonlyMap<string, Page>,\n configDir: string,\n /** The file `m` keeps one page's values in: the page's own for a `{page}` manifest. */\n fileOf: (pageAbs: string) => string,\n): void {\n if (index === null || m.keysRemoved.length === 0) return;\n for (const key of m.keysRemoved) {\n const moved = new Set<string>();\n for (const page of pages.values()) {\n const i = page.intents.get(key);\n if (i?.kind === \"in\" && i.manifest === m) moved.add(entryId(i.entry, m.join));\n }\n const stranded =\n m.join === PATH_JOIN\n ? [...index.byPath]\n .filter(([abs, values]) => {\n const sv = values.get(key);\n return sv !== undefined && sv.collection === m.collection && sv.file === fileOf(abs);\n })\n .map(([abs]) => toPosix(relative(configDir, abs)))\n : [...(index.byField.get(m.join) ?? new Map<string, ReadonlyMap<string, ExternalMetadataValue>>())]\n .filter(([, values]) => {\n const sv = values.get(key);\n return sv !== undefined && sv.file === m.file && sv.collection === m.collection;\n })\n .map(([value]) => value);\n const first = stranded.find((e) => !moved.has(entryId(e, m.join)));\n if (first !== undefined) {\n throw new DocmetaError(\n `Manifest ${m.file} names \"${first}\", which is not a page of collection ${m.collection}, so ${key} cannot leave its keys while that entry sets it. Fix the entry, or remove it.`,\n );\n }\n }\n}\n\n/**\n * A manifest's text, or null for a `{page}` manifest (proposal 0058) that\n * does not exist yet: a page with nothing kept there. A missing concrete\n * manifest is refused.\n */\nasync function readManifestText(path: string, file: string, perPage: boolean): Promise<string | null> {\n try {\n return await readFile(path, \"utf8\");\n } catch (err) {\n if (perPage && isMissing(err)) return null;\n throw new DocmetaError(`Manifest ${file} could not be read: ${errorMessage(err)}`);\n }\n}\n\n\nconst entryId = (entry: string, join: string): string =>\n join === PATH_JOIN ? toPosix(entry).replace(/^\\.\\//, \"\").replace(/\\/+/g, \"/\") : entry;\n/** A move's line, keyed by page label, manifest and key. */\n// NUL separates the parts, which assumes none of them holds a NUL. No supported OS allows one\n// in a page label or manifest path, and YAML frontmatter does not produce one in a key in practice.\nconst lineId = (page: string, manifest: string, key: string): string => `${page}\\0${manifest}\\0${key}`;\n\n/** Entry -> key -> 1-based line of the key, in a manifest's text. */\nfunction keyLines(text: string, join: string): Map<string, Map<string, number>> {\n const out = new Map<string, Map<string, number>>();\n const lc = new LineCounter();\n const doc = parseDocument(text, { lineCounter: lc, uniqueKeys: false });\n const root = doc.contents;\n if (!isMap(root)) return out;\n for (const pair of root.items) {\n const spelled = isScalar(pair.key) ? String(pair.key.value) : String(pair.key);\n if (!isMap(pair.value)) continue;\n const keys = new Map<string, number>();\n for (const kv of pair.value.items) {\n const name = isScalar(kv.key) ? String(kv.key.value) : String(kv.key);\n const range = isNode(kv.key) ? kv.key.range : undefined;\n if (range) keys.set(name, lc.linePos(range[0]).line);\n }\n out.set(entryId(spelled, join), keys);\n }\n return out;\n}\n\n/**\n * The config file a plan edits: the run's, else the family file at the git\n * root or cwd. `text` is what the edit starts from; `disk` is what the file\n * holds now, or null when there is no file.\n */\nasync function configTarget(\n ctx: RelocationContext,\n configDir: string,\n): Promise<{ path: string; text: string | null; disk: string | null }> {\n if (ctx.configPath !== undefined) {\n // Re-read rather than trust discovery's copy: an edit made since must not be written over.\n // Only a file removed since falls back to that copy; any other failure is refused.\n try {\n const text = await readFile(ctx.configPath, \"utf8\");\n return { path: ctx.configPath, text, disk: text };\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw new DocmetaError(\n `Config file ${configSource(ctx.configPath, ctx.cwd)} could not be read: ${errorMessage(err)}`,\n );\n }\n return { path: ctx.configPath, text: ctx.configFile?.text ?? null, disk: null };\n }\n }\n for (const name of FAMILY_CONFIG_NAMES) {\n const path = join(configDir, name);\n try {\n const text = await readFile(path, \"utf8\");\n return { path, text, disk: text };\n } catch {\n // Not this one.\n }\n }\n return { path: join(configDir, FAMILY_CONFIG_NAMES[0] ?? \"manni.config.yaml\"), text: null, disk: null };\n}\n\n/** The config text with the model's changes, comments and key order kept. */\nfunction editConfig(text: string | null, model: Model, source: string): string {\n const doc = parseDocument(text ?? \"\");\n const [problem] = doc.errors;\n if (problem !== undefined) throw new DocmetaError(`${source}: invalid YAML: ${problem.message}`);\n if (doc.contents !== null && !isMap(doc.contents)) {\n throw new DocmetaError(`${source}: top level must be a mapping.`);\n }\n const fail = (): never => {\n throw new DocmetaError(`Could not edit collections: in ${source}; make the change by hand.`);\n };\n const flowSeq = (node: unknown, quoted: boolean): void => {\n if (!isSeq(node)) return;\n node.flow = true;\n if (quoted) for (const item of node.items) if (isScalar(item)) item.type = \"QUOTE_DOUBLE\";\n };\n const manifestNode = (d: Document, file: string, keys: string[]): unknown => {\n const node = d.createNode({ file, keys });\n flowSeq(node.get(\"keys\", true), false);\n return node;\n };\n\n const declared = model.collections.length - model.created.length;\n const existing = doc.get(\"collections\", true);\n if (declared > 0 && !isSeq(existing)) fail();\n for (let i = 0; i < declared; i++) {\n const c = model.collections[i];\n const node = isSeq(existing) ? existing.items[i] : undefined;\n if (c === undefined || !isMap(node)) return fail();\n for (const added of model.pathsAdded.filter((p) => p.collection === c.name)) {\n const paths = node.get(\"paths\", true);\n if (!isSeq(paths)) return fail();\n const scalar = doc.createNode(added.path);\n const first = paths.items[0];\n if (isScalar(first) && first.type !== undefined) scalar.type = first.type;\n paths.add(scalar);\n }\n const refs = model.manifestsOf(c.name);\n for (const m of refs) {\n if (m.created) {\n let list = node.get(\"externalMetadata\", true);\n if (!isSeq(list)) {\n node.set(\"externalMetadata\", doc.createNode([]));\n list = node.get(\"externalMetadata\", true);\n }\n if (!isSeq(list)) return fail();\n list.add(manifestNode(doc, m.written, m.keysAdded));\n continue;\n }\n if (m.keysAdded.length === 0) continue;\n const entry = node.getIn([\"externalMetadata\", m.index], true);\n const keys = isMap(entry) ? entry.get(\"keys\", true) : undefined;\n if (!isSeq(keys)) return fail();\n for (const key of m.keysAdded) keys.add(doc.createNode(key));\n }\n // Removals last, highest index first, so earlier indices stay valid.\n const list = node.get(\"externalMetadata\", true);\n for (const m of [...refs].filter((r) => !r.created).sort((a, b) => b.index - a.index)) {\n if (m.keysRemoved.length === 0) continue;\n if (!isSeq(list)) return fail();\n const entry = list.items[m.index];\n const keys = isMap(entry) ? entry.get(\"keys\", true) : undefined;\n if (!isSeq(keys)) return fail();\n for (const key of m.keysRemoved) {\n const at = keys.items.findIndex((item) => (isScalar(item) ? String(item.value) : String(item)) === key);\n if (at >= 0) keys.delete(at);\n }\n if (keys.items.length === 0) list.delete(m.index);\n }\n if (isSeq(list) && list.items.length === 0) node.delete(\"externalMetadata\");\n }\n for (const created of model.created) {\n const c = model.collections.find((x) => x.name === created.name);\n /* c8 ignore next -- a created collection is in the model. */\n if (c === undefined) continue;\n const refs = model.manifestsOf(c.name).filter((m) => m.created);\n const node = doc.createNode({\n name: c.name,\n paths: c.paths,\n ...(refs.length > 0\n ? { externalMetadata: refs.map((m) => ({ file: m.written, keys: m.keysAdded })) }\n : {}),\n });\n flowSeq(node.get(\"paths\", true), true);\n const made = node.get(\"externalMetadata\", true);\n if (isSeq(made)) {\n for (const item of made.items) if (isMap(item)) flowSeq(item.get(\"keys\", true), false);\n }\n const seq = doc.get(\"collections\", true);\n if (isSeq(seq)) seq.add(node);\n else doc.set(\"collections\", doc.createNode([node]));\n }\n return doc.toString({ flowCollectionPadding: false });\n}\n\n/**\n * Read back the edited config the way discovery would: it parses, it\n * declares exactly the planned collections, and every other top-level key is\n * as it was. A config the tools cannot read is worse than a refused run.\n */\nfunction verifyConfig(\n before: string | null,\n after: string,\n expected: CollectionConfig[],\n source: string,\n): void {\n const fail = (why: string): never => {\n throw new DocmetaError(`Could not edit collections: in ${source}, so nothing was written. ${why}`);\n };\n let old: unknown;\n let now: unknown;\n try {\n old = before === null ? null : parseYaml(before);\n now = parseYaml(after);\n } catch (err) {\n return fail(errorMessage(err));\n }\n if (typeof now !== \"object\" || now === null || Array.isArray(now)) return fail(\"The result is not a mapping.\");\n const nowMap = now as Record<string, unknown>;\n const oldMap = typeof old === \"object\" && old !== null && !Array.isArray(old) ? (old as Record<string, unknown>) : {};\n const parsed = parseCollections(nowMap[\"collections\"], source, (m) => new DocmetaError(m));\n if (!deepEqual(parsed, expected)) return fail(\"The collections read back differently.\");\n const rest = (m: Record<string, unknown>): Record<string, unknown> =>\n Object.fromEntries(Object.entries(m).filter(([k]) => k !== \"collections\"));\n if (!deepEqual(rest(nowMap), rest(oldMap))) return fail(\"Another key would have changed.\");\n}\n\n// ---------------------------------------------------------------------------\n// The report.\n// ---------------------------------------------------------------------------\n\nfunction buildResult(input: {\n model: Model;\n pages: Page[];\n dryRun: boolean;\n lines: ReadonlyMap<string, number>;\n config: RelocateConfigResult;\n}): RelocateResult {\n const { model, pages, dryRun, lines } = input;\n const files: RelocateFileResult[] = [];\n for (const page of pages) {\n const moved: RelocateMove[] = [];\n const stayed: RelocateStay[] = [];\n const intents = orderedIntents(page);\n // A `{page}` manifest (proposal 0058) is named by the page's own file.\n const fileOf = (m: ManifestRef): string => model.fileFor(m, page.absPath).file;\n for (const [key, intent] of intents) {\n if (intent.kind === \"in\") moved.push({ key, to: \"page\", from: fileOf(intent.manifest), reason: \"preferred\" });\n }\n for (const [key, intent] of intents) {\n if (intent.kind !== \"out\") continue;\n const manifest = fileOf(intent.manifest);\n const line = dryRun ? undefined : lines.get(lineId(page.label, manifest, key));\n moved.push({\n key,\n to: \"manifest\",\n manifest,\n ...(line !== undefined ? { line } : {}),\n reason: intent.reason,\n });\n }\n for (const [key, intent] of intents) {\n if (intent.kind === \"stay\") stayed.push({ key, reason: intent.reason, detail: intent.detail });\n }\n if (moved.length > 0 || stayed.length > 0) files.push({ file: page.label, moved, stayed, beyond: page.beyond });\n }\n const touches = (m: ManifestRef, page: Page): boolean =>\n [...page.intents.values()].some((i) => (i.kind === \"in\" || i.kind === \"out\") && i.manifest === m);\n const manifests: RelocateManifestResult[] = model.manifests\n .filter(\n (m) =>\n m.created || m.keysAdded.length > 0 || m.keysRemoved.length > 0 || pages.some((p) => touches(m, p)),\n )\n .map((m) => {\n const keys = model.finalKeys(m);\n return {\n file: m.file,\n collection: m.collection,\n index: m.index,\n created: m.created,\n keysAdded: [...m.keysAdded],\n keysRemoved: [...m.keysRemoved],\n keys,\n undeclared: !m.implied && keys.length === 0 && !m.created,\n beyond: pages.filter(\n (p) =>\n p.beyond &&\n [...p.intents].some(\n ([k, i]) =>\n ((i.kind === \"in\" || i.kind === \"out\") && i.manifest === m) ||\n (i.kind === \"stay\" && (m.keysAdded.includes(k) || m.keysRemoved.includes(k))),\n ),\n ).length,\n };\n });\n return {\n dryRun,\n config: input.config,\n manifests,\n files,\n summary: {\n files: files.length,\n moved: files.reduce((n, f) => n + f.moved.length, 0),\n stayed: files.reduce((n, f) => n + f.stayed.length, 0),\n manifestsCreated: manifests.filter((m) => m.created).length,\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Applying.\n// ---------------------------------------------------------------------------\n\n/**\n * Write a plan: manifests, then the config, then the pages, each atomically.\n * Afterwards the context's collections (the same objects the caller's run\n * holds) declare what the config now declares, a created collection is\n * appended to both lists, and a created config sets `configDir` and\n * `configPath`. Returns the report with each manifest line.\n *\n * The run is all or nothing, as far as the disk allows. A file that changed\n * since planning is refused before anything is written. A write that fails\n * puts every file already written back as planning found it, removing the\n * ones this run created, and the context is left untouched. Without that, a\n * value leaving a manifest could be in neither the manifest nor the page.\n *\n * Throws `DocmetaError` for a changed or unreadable file and for a failed\n * write, naming any file that could not be put back.\n */\nexport async function applyRelocation(\n ctx: RelocationContext,\n plan: RelocationPlan,\n io: RelocationIo = {},\n): Promise<RelocateResult> {\n // A per-page manifest (proposal 0058) may be the first file in its\n // directory. A page and the config already have theirs.\n const write = io.write ?? ((path: string, text: string) => writeFileAtomic(path, text, { createParents: true }));\n const remove = io.remove ?? ((path: string) => unlink(path));\n const label = (w: RelocationWrite): string =>\n w.kind === \"config\" ? configSource(w.path, ctx.cwd) : reported(w.path, ctx.base);\n\n for (const w of plan.writes) {\n let now: string | null;\n try {\n now = await readFile(w.path, \"utf8\");\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw new DocmetaError(`${label(w)} could not be read: ${errorMessage(err)}`);\n }\n now = null;\n }\n if (now !== w.before) {\n throw new DocmetaError(\n `${label(w)} changed after the relocation was planned, so nothing was written. Run the command again.`,\n );\n }\n }\n\n // Put back what `done` wrote, last first, and word the error the run throws.\n const rollBack = async (done: RelocationWrite[], head: string): Promise<DocmetaError> => {\n const failed: { file: string; reason: string }[] = [];\n for (const w of [...done].reverse()) {\n try {\n if (w.before === null) await remove(w.path);\n else await write(w.path, w.before);\n } catch (err) {\n failed.push({ file: label(w), reason: errorMessage(err) });\n }\n }\n const [first] = failed;\n if (first === undefined) {\n if (done.length === 0) return new DocmetaError(`${head} Nothing was changed.`);\n const files = done.length === 1 ? \"the file already written was\" : `the ${String(done.length)} files already written were`;\n return new DocmetaError(`${head} Nothing was changed: ${files} restored.`);\n }\n const one = failed.length === 1;\n return new DocmetaError(\n `${head} The run was rolled back, but ${list(failed.map((f) => f.file))} could not be restored: ${first.reason}. Restore ${one ? \"it\" : \"them\"} from version control.`,\n );\n };\n\n const written: RelocationWrite[] = [];\n for (const w of plan.writes) {\n try {\n await write(w.path, w.text);\n } catch (err) {\n throw await rollBack(written, `Could not write ${label(w)}: ${errorMessage(err)}.`);\n }\n written.push(w);\n }\n\n if (plan.writes.some((w) => w.kind === \"config\")) {\n const narrowed = ctx.collections.length < ctx.declaredCollections.length;\n for (const next of plan.collections) {\n const have = ctx.declaredCollections.find((c) => c.name === next.name);\n if (have !== undefined) {\n have.paths = next.paths;\n have.externalMetadata = next.externalMetadata;\n continue;\n }\n ctx.declaredCollections.push(next);\n if (!narrowed) ctx.collections.push(next);\n }\n ctx.configDir ??= plan.configDir;\n ctx.configPath ??= plan.configPath;\n }\n return {\n ...plan.result,\n dryRun: false,\n files: plan.result.files.map((f) => ({\n ...f,\n moved: f.moved.map((mv) => {\n if (mv.to !== \"manifest\") return mv;\n const line = plan.lines.get(lineId(f.file, mv.manifest, mv.key));\n return line === undefined ? mv : { ...mv, line };\n }),\n })),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Offers: what the writers' (P1) and validate's (P2) prompts say.\n// ---------------------------------------------------------------------------\n\n/** One collection's share of a plan, as a prompt words it. */\nexport interface RelocationOffer {\n collection: string;\n /** The collection is created, with these paths (§3 case 2). */\n createsCollection?: { paths: string[] };\n /** Run targets appended to the collection's `paths:` (§3 case 3). */\n pathsAdded: string[];\n /** The config file the changes go to, as the run names it. */\n config: string | undefined;\n manifests: { file: string; created: boolean; keysAdded: string[]; keysRemoved: string[] }[];\n /** Keys leaving pages for a manifest, and how many values and pages that is. */\n keysOut: string[];\n valuesOut: number;\n pagesOut: number;\n /** Values leaving a manifest for pages, and which manifests give them up. */\n valuesIn: number;\n manifestsIn: string[];\n}\n\nfunction buildOffers(model: Model, pages: Page[], result: RelocateResult, config: string | undefined): RelocationOffer[] {\n const names = dedupe(result.manifests.map((m) => m.collection));\n return names.map((name) => {\n const manifests = result.manifests.filter((m) => m.collection === name);\n const outs = pages.flatMap((p) =>\n [...p.intents].filter(([, i]) => i.kind === \"out\" && i.manifest.collection === name).map(([k]) => ({ page: p.label, key: k })),\n );\n const ins = pages.flatMap((p) =>\n [...p.intents]\n .filter(([, i]) => i.kind === \"in\" && i.manifest.collection === name)\n .map(([, i]) => (i.kind === \"in\" ? i.manifest.file : \"\")),\n );\n const created = model.created.find((c) => c.name === name);\n return {\n collection: name,\n ...(created !== undefined ? { createsCollection: { paths: [...created.paths] } } : {}),\n pathsAdded: model.pathsAdded.filter((p) => p.collection === name).map((p) => p.path),\n config,\n manifests: manifests.map((m) => ({\n file: m.file,\n created: m.created,\n keysAdded: [...m.keysAdded],\n keysRemoved: [...m.keysRemoved],\n })),\n keysOut: dedupe(manifests.flatMap((m) => m.keysAdded)),\n valuesOut: outs.length,\n pagesOut: new Set(outs.map((o) => o.page)).size,\n valuesIn: ins.length,\n manifestsIn: dedupe(ins),\n };\n });\n}\n\nconst count = (n: number, noun: string): string => `${n} ${noun}${n === 1 ? \"\" : \"s\"}`;\nconst list = (xs: readonly string[]): string => xs.join(\", \");\n\n/**\n * The two lines a prompt puts for one offer: `notice` is a diagnostic (the\n * caller adds the `manni: ` prefix) and `question` goes to `Confirm`, which\n * appends `[y/N] `.\n *\n * `write` is P1, asked by `derive`, `fill` and `query` before a value that\n * prefers external metadata is written. `validate` is P2, asked after the\n * report.\n */\nexport function offerPrompt(offer: RelocationOffer, kind: \"write\" | \"validate\"): { notice: string; question: string } {\n const config = offer.config ?? FAMILY_CONFIG_NAMES[0] ?? \"manni.config.yaml\";\n if (kind === \"validate\") {\n const parts: string[] = [];\n if (offer.valuesOut > 0) {\n parts.push(\n `${count(offer.valuesOut, \"value\")} in ${count(offer.pagesOut, \"page\")} ${offer.valuesOut === 1 ? \"prefers\" : \"prefer\"} external metadata`,\n );\n }\n if (offer.valuesIn > 0) {\n parts.push(\n `${count(offer.valuesIn, \"value\")} in ${list(offer.manifestsIn)} ${offer.valuesIn === 1 ? \"prefers\" : \"prefer\"} the page`,\n );\n }\n const changes: string[] = [];\n if (offer.createsCollection !== undefined) {\n changes.push(`create collection ${offer.collection} (paths: ${list(offer.createsCollection.paths)})`);\n }\n for (const p of offer.pathsAdded) changes.push(`add ${p} to collection ${offer.collection}'s paths`);\n for (const m of offer.manifests) {\n if (m.created) changes.push(`create ${m.file}`);\n if (m.keysRemoved.length > 0) changes.push(`remove ${list(m.keysRemoved)} from ${m.file}'s keys`);\n if (!m.created && m.keysAdded.length > 0) changes.push(`add ${list(m.keysAdded)} to ${m.file}'s keys`);\n }\n return {\n notice: `in collection ${offer.collection}, ${parts.join(\" and \")}.`,\n question: changes.length === 0 ? \"Move them? \" : `Move them (${changes.join(\", \")})? `,\n };\n }\n const keys = list(offer.keysOut);\n const prefer = offer.keysOut.length === 1 ? \"which the schema prefers\" : \"which their schemas prefer\";\n const move = offer.pagesOut > 0 ? `move them out of ${count(offer.pagesOut, \"page\")}` : undefined;\n const tail = (steps: string[]): string => {\n const all = move === undefined ? steps : [...steps, move];\n if (all.length === 1) return `${capital(all[0] ?? \"\")}? `;\n if (all.length === 2) return `${capital(all[0] ?? \"\")} and ${all[1] ?? \"\"}? `;\n return `${capital(all.slice(0, -1).join(\", \"))}, and ${all.at(-1) ?? \"\"}? `;\n };\n const created = offer.manifests.find((m) => m.created);\n if (offer.createsCollection !== undefined) {\n const make = `Create collection ${offer.collection} (paths: ${list(offer.createsCollection.paths)}), with ${created?.file ?? `${offer.collection}.metadata.yaml`}, in ${config}`;\n return {\n notice: `no collection has a manifest for ${keys}, ${prefer} in external metadata.`,\n question: move === undefined ? `${make}? ` : `${make}, and ${move}? `,\n };\n }\n const steps: string[] = offer.pathsAdded.map((p) => `add ${p} to collection ${offer.collection}'s paths`);\n if (created !== undefined) steps.push(`create ${created.file}`, `add it to ${config}`);\n for (const m of offer.manifests) {\n if (!m.created && m.keysAdded.length > 0) steps.push(`add ${list(m.keysAdded)} to ${m.file}'s keys`);\n }\n return {\n notice: `collection ${offer.collection} has no manifest for ${keys}, ${prefer} in external metadata.`,\n question: tail(steps),\n };\n}\n\nfunction capital(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/** The plan's offers, one per collection whose manifests the plan changes. */\nexport function relocationOffers(plan: RelocationPlan): RelocationOffer[] {\n return plan.offers;\n}\n","/**\n * Collection views, and the membership adapter that decides what a collection\n * contains.\n *\n * `memberOf` is proposal 0041's rule 10: which collections a file belongs to,\n * as path arithmetic against the config file's directory. It is what external\n * metadata attaches to, what an `overrides[].collection` resolves through, and\n * — since 0041 rule 7 — what a SQL view holds.\n *\n * One meaning of \"collection\", everywhere. 0027 built each view from the files\n * an override *won schema resolution for*, so views were disjoint, only a\n * collection an override pointed at had a view at all, and a file whose own\n * `$schema` outranked the override was announced as not being in it. 0041\n * makes a view the set the config says it is: every declared collection is a\n * view, two views may overlap, and `FROM authors` reads as \"the files the\n * authors collection selects\".\n *\n * That restores 0021's founding rule, which 0027 had to bend: a plain read\n * resolves no schemas. Nothing in this module resolves anything, so there is\n * no trust refusal to demote a file over, no per-file walk to pay for, and no\n * notice to print. Resolution still honours `overrides[].collection` — it\n * matches through `memberOf` in `resolve-schema.ts`, which is untouched.\n *\n * Shared by both projection consumers — `query` and the corpus checks\n * `validate` runs — so the two cannot drift on what a collection contains.\n */\nimport type { DatabaseSync } from \"node:sqlite\";\nimport { isAbsolute, relative, resolve as resolvePath, sep } from \"node:path\";\nimport { isMember, type CollectionConfig } from \"../../shared/collections.js\";\nimport { STDIN_LABEL } from \"./load-files.js\";\nimport { quoteIdent, type ProjectionEntry } from \"./projection.js\";\n\n/**\n * Names of the collections this file belongs to, in declaration order.\n *\n * Where the two bases meet. A run labels files relative to `base` — the\n * working directory for positional paths, the config's directory otherwise —\n * while membership is decided relative to the config file's directory, because\n * that is where a collection's globs were written (0004). So the label is\n * resolved against `base` and then measured from `configDir`.\n *\n * Pure path arithmetic (0041 rule 10): no `stat`, nothing that can fail, and\n * nothing that costs per file. Stdin and anything outside `configDir` are\n * members of nothing — stdin because there is no file behind it, and `isMember`\n * refuses a `../` path on its own.\n */\nexport function memberOf(\n collections: readonly CollectionConfig[],\n configDir: string,\n base: string,\n label: string,\n): string[] {\n if (collections.length === 0) return [];\n if (label === STDIN_LABEL) return [];\n const rel = relative(configDir, resolvePath(base, label))\n .split(sep)\n .join(\"/\");\n // `relative` gives back an *absolute* path when the two sides share no root\n // — a different drive letter on Windows. That is as far outside the config\n // directory as a path can be, and it carries no `../` for `isMember` to\n // refuse, so it is refused here.\n if (isAbsolute(rel)) return [];\n return collections.filter((c) => isMember(c, rel)).map((c) => c.name);\n}\n\n/**\n * Narrow a walked file set to the files that belong to a selected collection\n * (proposal 0041 rule 9).\n *\n * The walk applies the family-wide ignores and `--exclude` only, because a\n * collection's `paths:` and `exclude:` are two halves of one statement and the\n * walk sees just the first half. Without this second pass a collection's\n * `exclude:` shaped its SQL view but not what a bare run read, so one config\n * gave two different answers about the same collection — the ambiguity 0041\n * exists to remove.\n *\n * Apply it **only** when the inputs came from the collections. A path someone\n * typed is theirs, and no collection's exclusions filter it (rule 3); the\n * caller decides, which is why this takes the already-walked list rather than\n * consulting `fromCollections` itself.\n */\nexport function retainMembers(\n files: readonly string[],\n membersFor: (label: string) => readonly string[],\n): string[] {\n return files.filter((label) => membersFor(label).length > 0);\n}\n\n/** One collection, with the loaded files that belong to it. */\nexport interface Collection {\n name: string;\n /** `_path` labels of the member files. May be empty — an empty view. */\n members: string[];\n}\n\n/**\n * The declared collection names, in declaration order — the one list every\n * \"is this a collection?\" consumer shares: the view builder below, and\n * `query`'s eager-build trigger and lazy-retry match. Callers that compare\n * case-insensitively use `String.prototype.toLowerCase`, whose Unicode fold\n * is looser than SQLite's ASCII-only fold — that mismatch can only\n * over-trigger a harmless eager build or rebuild, never miss a real match.\n */\nexport function collectionNames(\n collections: readonly CollectionConfig[] | undefined,\n): string[] {\n return (collections ?? []).map((c) => c.name);\n}\n\nexport interface CollectionParams {\n /**\n * Every collection the config **declares** — not just the ones `--collection`\n * selected, and not just the ones an override points at. Each one is a view\n * (0041 rule 11), so narrowing a run never turns `FROM blog` into a SQL\n * error; it turns it into a view holding whatever of `blog` the run loaded.\n * Optional so the checks' run context can be this very shape; absent, or\n * empty, means there are no collections and so no views.\n */\n collections?: readonly CollectionConfig[];\n /**\n * The config file's directory: what a collection's globs are measured from\n * (0004). Only read when there is a collection to build a view for, which is\n * only ever true when a config governs the run.\n */\n configDir?: string;\n /** Directory the run's file labels are relative to (`RunConfig.base`). */\n base?: string;\n}\n\n/**\n * Compute every declared collection's member list from the loaded entries.\n *\n * Membership is the config's own arithmetic — `memberOf`, the same function\n * external metadata and `overrides[].collection` go through — so a view holds\n * exactly the loaded files the collection selects, and a file in two\n * collections is in both views. Nothing here resolves a schema, opens a file,\n * or can fail.\n */\nexport function collectCollections(\n entries: readonly ProjectionEntry[],\n params: CollectionParams,\n): Collection[] {\n const declared = params.collections ?? [];\n if (declared.length === 0) return [];\n // A collection can only be declared by a config file, so both bases are set\n // whenever there is a view to build; the fallbacks keep the arithmetic total\n // rather than optional.\n const base = params.base ?? \".\";\n const configDir = params.configDir ?? base;\n\n const members = new Map<string, string[]>();\n for (const entry of entries) {\n for (const name of memberOf(declared, configDir, base, entry.label)) {\n const list = members.get(name);\n if (list) list.push(entry.label);\n else members.set(name, [entry.label]);\n }\n }\n return declared.map((c) => ({ name: c.name, members: members.get(c.name) ?? [] }));\n}\n\n/** One member path as a SQL string literal (doubling internal quotes). */\nfunction quoteSqlString(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\n/**\n * Create one view per collection on an open database that already holds the\n * `docs` table.\n *\n * Each view is built from the computed member list — literal paths, `WHERE 0`\n * for an empty collection — never from a SQL translation of the config glob:\n * picomatch and SQLite `GLOB` are different languages, and membership was\n * already decided by the code that owns the decision. The IN-list scales past\n * any real corpus (0027 § stress test 4: SQLite's SQL-length ceiling is\n * ~1 GB; ten thousand long-ish paths are under a megabyte).\n *\n * Views live in `sqlite_master`, outside the two snapshots effect judgment\n * diffs (`SELECT * FROM docs`, `PRAGMA table_info(docs)`), so the effect gate\n * never sees them — and a `--db` export carries them, which is a feature.\n */\nexport function createCollectionViews(\n db: DatabaseSync,\n collections: readonly Collection[],\n): void {\n for (const c of collections) {\n const where =\n c.members.length === 0\n ? \"0\"\n : `_path IN (${c.members.map(quoteSqlString).join(\", \")})`;\n db.exec(\n `CREATE VIEW ${quoteIdent(c.name)} AS SELECT * FROM docs WHERE ${where}`,\n );\n }\n}\n","/**\n * The SQL projection of a metadata corpus — the `docs` table both `query`\n * (proposal 0021) and the named corpus checks (proposal 0026) run over.\n *\n * One file, one row: the four system columns plus one column per top-level\n * metadata key across the corpus. `query` adds statement-specific columns and\n * effect-judging on top; checks read the same table and nothing else. The\n * table-building lives here so the two entry points cannot drift.\n */\nimport type { DatabaseSync } from \"node:sqlite\";\nimport { DocmetaError, type ExtractedMetadata } from \"../types.js\";\n\n/**\n * The columns every `docs` table carries, reserved so ordinary frontmatter can\n * never shadow them. A frontmatter key with exactly one of these names is not\n * lifted to a column and stays reachable as `_data ->> '$.<key>'`; any other\n * `_`-prefixed key lifts normally — the reservation is four names, not a\n * namespace grab (proposal 0021 § stress test 4).\n */\nexport const SYSTEM_COLUMNS = [\"_path\", \"_format\", \"_present\", \"_data\"] as const;\nexport const RESERVED: ReadonlySet<string> = new Set<string>(SYSTEM_COLUMNS);\n\n/** What `node:sqlite` accepts as a bound parameter. */\nexport type SqlValue = null | number | bigint | string;\n\n/** One loaded file, as the projection needs it: its label and its extraction. */\nexport interface ProjectionEntry {\n label: string;\n extracted: ExtractedMetadata;\n}\n\n/** Any key becomes a legal quoted identifier by doubling internal quotes. */\nexport function quoteIdent(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n\n/**\n * One frontmatter value, as SQLite stores it: booleans as 1/0 (`node:sqlite`\n * refuses to bind a boolean), arrays and objects as JSON text (which\n * `json_each` and `->>` then query directly), non-finite numbers as NULL\n * (SQLite has no NaN — it would store NULL anyway, this just does it without\n * an engine error).\n */\nexport function bindValue(value: unknown): SqlValue {\n if (value === undefined || value === null) return null;\n switch (typeof value) {\n case \"boolean\":\n return value ? 1 : 0;\n case \"number\":\n return Number.isFinite(value) ? value : null;\n case \"bigint\":\n case \"string\":\n return value;\n default:\n return JSON.stringify(value);\n }\n}\n\n/**\n * Data columns for a corpus: the union of top-level keys across `entries` —\n * the same scan boundary `schemas infer` chose — plus any `extraKeys` the\n * caller's statement names (a SET target no file has yet still deserves a\n * column). Sorted, so the column order (and any `SELECT *`) is deterministic\n * regardless of file order.\n */\nexport function corpusDataColumns(\n entries: readonly ProjectionEntry[],\n extraKeys: Iterable<string> = [],\n): string[] {\n const keys = new Set<string>();\n for (const { extracted } of entries) {\n for (const key of Object.keys(extracted.data)) {\n if (key !== \"\" && !RESERVED.has(key)) keys.add(key);\n }\n }\n for (const key of extraKeys) {\n if (key !== \"\" && !RESERVED.has(key)) keys.add(key);\n }\n return [...keys].sort();\n}\n\n/**\n * Create and load the `docs` table on an open database.\n *\n * Data columns get no type affinity, so SQLite stores exactly the value each\n * file had and never coerces one file's string into another's number. One\n * transaction for the bulk load: each bare run() would otherwise commit on its\n * own, which is where a large corpus spends its load time.\n */\nexport function createDocsTable(\n db: DatabaseSync,\n entries: readonly ProjectionEntry[],\n dataColumns: readonly string[],\n): void {\n db.exec(\n `CREATE TABLE docs (\"_path\" TEXT PRIMARY KEY, \"_format\" TEXT, \"_present\" INTEGER, \"_data\" TEXT${dataColumns\n .map((c) => `, ${quoteIdent(c)}`)\n .join(\"\")})`,\n );\n const insert = db.prepare(\n `INSERT INTO docs VALUES (${[\"?\", \"?\", \"?\", \"?\", ...dataColumns.map(() => \"?\")].join(\", \")})`,\n );\n db.exec(\"BEGIN\");\n // Committed or rolled back, never left open: a caller may keep using the\n // handle after a failed insert, and every later statement would otherwise\n // run inside the half-built transaction.\n let committed = false;\n try {\n for (const { label, extracted } of entries) {\n insert.run(\n label,\n extracted.format,\n extracted.present ? 1 : 0,\n JSON.stringify(extracted.data),\n ...dataColumns.map((c) => bindValue(extracted.data[c])),\n );\n }\n db.exec(\"COMMIT\");\n committed = true;\n } finally {\n if (!committed) db.exec(\"ROLLBACK\");\n }\n}\n\n/**\n * Register `lineFor(path, key)` as a SQL function on the run's database, so a\n * statement can name the source line a metadata key sits on (proposal 0026).\n *\n * Backed by each entry's `extracted.lineFor` — the contract every extractor\n * already fulfills for annotations — through the same `db.function` mechanism\n * that registers `explicit_null()`, plus `deterministic: true`: the answer\n * depends only on the arguments for the life of the statement, which lets\n * SQLite fold repeated calls. `NULL` for an unknown path, a key the extractor\n * cannot place, or a non-string argument.\n */\nexport function registerLineFor(\n db: DatabaseSync,\n entries: readonly ProjectionEntry[],\n): void {\n const byLabel = new Map(entries.map((e) => [e.label, e.extracted]));\n db.function(\"lineFor\", { deterministic: true }, (path, key) => {\n if (typeof path !== \"string\" || typeof key !== \"string\") return null;\n return byLabel.get(path)?.lineFor(key) ?? null;\n });\n}\n\n/**\n * Refuse a second statement instead of silently dropping it.\n *\n * `prepare()` compiles the first statement and ignores the rest, so\n * `SELECT 1; DROP TABLE docs` would run the SELECT and quietly skip the DROP —\n * a request half-honored with exit 0, the false-green shape 0016 exists to\n * keep out. The scan skips string literals, quoted identifiers, and both\n * comment forms; a trailing `;` (or several) is a terminator, not a chain.\n */\nexport function assertSingleStatement(sql: string): void {\n const cut = topLevelSemicolon(sql);\n if (cut === -1) return;\n if (!isTrivia(sql.slice(cut + 1))) {\n throw new DocmetaError(\n \"Run a single SQL statement per query; text after the first `;` would be silently ignored.\",\n );\n }\n}\n\n/**\n * The scanner primitives every SQL micro-lexer in the codebase is built on —\n * statement splitting and the parameter scan below, `query`'s SET/INSERT\n * target scans, and the 0028 catalog-CHECK parser. One implementation of\n * \"skip the region whose contents are data, not syntax\", so the consumers\n * cannot drift on what a string or a comment is.\n */\n\n/** Does `sql[i]` open a string literal or a quoted/bracketed identifier? */\nexport function startsStringOrIdent(sql: string, i: number): boolean {\n const ch = sql[i];\n return ch === \"'\" || ch === '\"' || ch === \"`\" || ch === \"[\";\n}\n\n/** Does a line comment (`--`) or block comment start at `i`? */\nexport function startsComment(sql: string, i: number): boolean {\n const ch = sql[i];\n return (\n (ch === \"-\" && sql[i + 1] === \"-\") || (ch === \"/\" && sql[i + 1] === \"*\")\n );\n}\n\n/**\n * Index just past a string literal or quoted/bracketed identifier opening at\n * `i` (`sql[i]` must satisfy `startsStringOrIdent`). The three quote forms\n * treat a doubled quote as an escape — `'a''b'` is one literal — and an\n * unterminated one consumes the rest of the input (returns `sql.length`).\n * A bracket identifier scans plainly to `]`: SQLite brackets have no `]]`\n * escape (unlike T-SQL), so no doubling branch — and an unterminated one\n * returns `sql.length + 1`, one past the close the terminated form counts,\n * which `readIdentifier`'s `end - 1` slicing relies on.\n */\nexport function skipStringOrIdent(sql: string, i: number): number {\n const quote = sql[i];\n if (quote === \"[\") {\n let j = i + 1;\n while (j < sql.length && sql[j] !== \"]\") j++;\n return j + 1;\n }\n let j = i + 1;\n while (j < sql.length) {\n if (sql[j] === quote) {\n if (sql[j + 1] === quote) {\n j += 2;\n continue;\n }\n return j + 1;\n }\n j++;\n }\n return j;\n}\n\n/**\n * Index just past a comment opening at `i` (`sql` must satisfy\n * `startsComment` there). A line comment ends past its newline, a block\n * comment past its closer; either unterminated consumes the rest of the\n * input. Consuming the line comment's newline is safe because every consumer\n * treats a bare newline as trivia.\n */\nexport function skipComment(sql: string, i: number): number {\n if (sql[i] === \"-\") {\n let j = i + 2;\n while (j < sql.length && sql[j] !== \"\\n\") j++;\n return j < sql.length ? j + 1 : j;\n }\n const end = sql.indexOf(\"*/\", i + 2);\n return end === -1 ? sql.length : end + 2;\n}\n\n/**\n * Index of the first `;` outside literals, identifiers, and comments.\n *\n * Parenthesis depth is deliberately not tracked: in valid SQLite, the only\n * semicolons outside strings are statement terminators — the grammar has no\n * parenthesized position where one may appear — so depth would be state with\n * nothing to distinguish. (Trigger bodies, the one construct with interior\n * semicolons, never reach here: the docs projection has no triggers.)\n */\nfunction topLevelSemicolon(sql: string): number {\n let i = 0;\n while (i < sql.length) {\n if (startsStringOrIdent(sql, i)) {\n i = skipStringOrIdent(sql, i);\n } else if (startsComment(sql, i)) {\n i = skipComment(sql, i);\n } else if (sql[i] === \";\") {\n return i;\n } else {\n i++;\n }\n }\n return -1;\n}\n\n/**\n * The one grammar for a named parameter's bare name. The scan below matches\n * it as a prefix; `isParamName` answers for a whole string — exported so the\n * CLI's `--param` validation cannot drift from what the scan recognizes.\n */\nconst PARAM_NAME_HEAD = /^[A-Za-z_][A-Za-z0-9_]*/;\nexport function isParamName(name: string): boolean {\n return PARAM_NAME_HEAD.exec(name)?.[0] === name;\n}\n\n/**\n * Named-parameter tokens (`$name`, `:name`, `@name`) the statement references\n * outside string literals, quoted identifiers, and comments — the same skip\n * rules as `topLevelSemicolon`, for the same reason: text inside a literal is\n * data, not syntax (proposal 0029).\n *\n * The tokens are returned as written, prefix included, first occurrence only.\n * The grammar is deliberately narrow: a prefix character must be followed\n * immediately by an identifier (`[A-Za-z_][A-Za-z0-9_]*`), so a bare `$`, a\n * spaced `:`, and a doubled `::` are all operators-or-noise, never parameters.\n *\n * One bare name under two prefixes (`$p` and `:p` in one statement) refuses\n * here: the engine rejects it anyway, but as a generic \"conflicting names\"\n * SQL error with neither spelling named.\n *\n * Why this exists: the engine throws on an *extra* bound parameter, but a\n * parameter the SQL references with nothing bound silently binds NULL — which\n * matches nothing, and a zero-row `--check` is a passing CI gate. The caller\n * uses this list to refuse that false green before the statement runs.\n */\nexport function collectNamedParameters(sql: string): string[] {\n const tokens: string[] = [];\n const seen = new Set<string>();\n const prefixOf = new Map<string, string>();\n let i = 0;\n while (i < sql.length) {\n const ch = sql[i];\n if (startsStringOrIdent(sql, i)) {\n i = skipStringOrIdent(sql, i);\n } else if (startsComment(sql, i)) {\n i = skipComment(sql, i);\n } else if (ch === \"$\" || ch === \":\" || ch === \"@\") {\n if (ch === \":\" && sql[i + 1] === \":\") {\n // `::` is no parameter; consume both so neither colon starts one.\n i += 2;\n continue;\n }\n const m = PARAM_NAME_HEAD.exec(sql.slice(i + 1));\n if (!m) {\n i++;\n continue;\n }\n const token = ch + m[0];\n const priorPrefix = prefixOf.get(m[0]);\n if (priorPrefix !== undefined && priorPrefix !== ch) {\n throw new DocmetaError(\n `The statement references both ${priorPrefix}${m[0]} and ${token} — one name under two prefixes, which the engine rejects as conflicting. Use one spelling throughout.`,\n );\n }\n prefixOf.set(m[0], ch);\n if (!seen.has(token)) {\n seen.add(token);\n tokens.push(token);\n }\n i += 1 + m[0].length;\n } else {\n i++;\n }\n }\n return tokens;\n}\n\n/**\n * The statement with leading whitespace and comments removed — the first real\n * token, for the callers that refuse a statement by name (`query`'s\n * ATTACH/VACUUM gate, and the checks' twin of it). Lived in query.ts until\n * the checks needed the identical scan.\n */\nexport function stripLeadingTrivia(sql: string): string {\n let i = 0;\n for (;;) {\n while (i < sql.length && /\\s/.test(sql[i] ?? \"\")) i++;\n if (startsComment(sql, i)) {\n i = skipComment(sql, i);\n continue;\n }\n return sql.slice(i);\n }\n}\n\n/** Only whitespace, comments, and bare `;` — legal after the terminator. */\nfunction isTrivia(text: string): boolean {\n let i = 0;\n while (i < text.length) {\n const ch = text[i];\n if (ch === undefined || /\\s/.test(ch) || ch === \";\") {\n i++;\n continue;\n }\n if (startsComment(text, i)) {\n i = skipComment(text, i);\n continue;\n }\n return false;\n }\n return true;\n}\n\n/**\n * `node:sqlite`, imported on first use only.\n *\n * Two reasons this is not a top-level import. A static import would load the\n * module for every docmeta invocation, `validate` runs included. And on the\n * Node 24 engines floor the module is a release candidate that announces\n * itself with an ExperimentalWarning on load — which would open every CI log\n * with a scare line — so exactly that one warning is filtered while the\n * import runs. Delete the filter when `node:sqlite` reaches Stable.\n */\nlet sqliteModule: Promise<typeof import(\"node:sqlite\")> | undefined;\nexport function loadSqlite(): Promise<typeof import(\"node:sqlite\")> {\n sqliteModule ??= (async () => {\n // Bound, so the capture is a standalone function twice over: callable\n // here without a `this` surprise, and safe to leave installed as the\n // restored property.\n const original = process.emitWarning.bind(process);\n const filtered: typeof process.emitWarning = (warning, ...rest) => {\n const text = typeof warning === \"string\" ? warning : warning.message;\n if (text.includes(\"SQLite is an experimental feature\")) return;\n Reflect.apply(original, process, [warning, ...rest]);\n };\n process.emitWarning = filtered;\n try {\n return await import(\"node:sqlite\");\n } finally {\n process.emitWarning = original;\n }\n })();\n return sqliteModule;\n}\n","/**\n * The manifest splice writer: rewrite one owned value for one document entry\n * of an external-metadata manifest (proposal 0037), and change no other byte.\n *\n * `manni cite` keeps a page's `citations` in a manifest and is the first\n * writer of one. Since proposal 0047, `meta query` routes a write to an\n * owned key here too, and `renameManifestEntry` follows a `_path` move. It is text in, text out: the caller reads and writes the\n * file.\n *\n * The design is the one `frontmatter-write.ts` uses for TOML. The document is\n * parsed once for its node ranges, and exactly one range of the original text\n * is replaced. So everything outside that range survives by construction\n * rather than by careful re-emission: comments, key order, quoting, blank\n * lines, and the line endings. The primitives live in `yaml-splice.ts`,\n * which the frontmatter writer shares. Three edits are possible:\n *\n * - **Replace.** The key is present in the entry. Its value's text is\n * replaced by the new value as block YAML at the key's indentation.\n * Comments inside the old value go with it, since they described it. A\n * comment on the key's own line stays.\n * - **Insert.** The entry is present and the key is not. The key is added\n * after the entry's last line, at the indentation of its other keys.\n * - **Append.** The entry is absent. It is added after the last entry, keyed\n * by path, or by the join value when the manifest joins on a field (0039),\n * and spaced from the one before it the way the others are.\n *\n * Every result is read back before it is returned, and the entry's key must\n * deep-equal the value while every other value is unchanged. A serializer\n * bug, or a value YAML cannot hold, is then a refusal rather than a damaged\n * manifest.\n */\nimport { posix } from \"node:path\";\nimport {\n LineCounter,\n isMap,\n isNode,\n isScalar,\n parseDocument,\n stringify,\n type Document,\n type Pair,\n type YAMLMap,\n} from \"yaml\";\nimport { DocmetaError } from \"../types.js\";\nimport { deepEqual } from \"../extractors/patch-util.js\";\nimport { FILE_SCHEMA_KEY } from \"./resolve-schema.js\";\nimport { PATH_JOIN } from \"./external-metadata.js\";\nimport {\n blockLines,\n colOf,\n colonEnd,\n contentEnd,\n detectEol,\n detectStyle,\n emptySource,\n insertKey,\n keyLines,\n keyString,\n lineEnd,\n rangeOf,\n replaceBlockValue,\n replaceFlowValue,\n type Edit,\n type Style,\n} from \"./yaml-splice.js\";\n\nexport interface SpliceManifestOptions {\n /**\n * The document entry: its path relative to the config's directory, or its\n * value of the join field when `join` names one. A path entry matches\n * however the manifest spells it (`./docs/a.md` is `docs/a.md`); a join\n * value matches exactly.\n */\n entry: string;\n /** The owned key to write. */\n key: string;\n /** The value to write. Mappings and lists are written in block style. */\n value: unknown;\n /** `path` (the default) or the frontmatter field the manifest joins on. */\n join?: string;\n /** The manifest as the run reports it, for error messages. */\n file?: string;\n}\n\nexport interface SplicedManifest {\n /** The whole manifest, with the one value rewritten. */\n text: string;\n /** 1-based line where the written value now starts. */\n line: number;\n}\n\n/**\n * Rewrite `options.key` of `options.entry` in the manifest `text` to\n * `options.value`, and return the new text and the line the value starts on.\n *\n * Throws `DocmetaError`, and never returns a partial result, when:\n * - the text is not valid YAML, or its top level is not a mapping;\n * - the entry is named twice, or is not a mapping;\n * - the key is set twice in the entry, or is `$schema`;\n * - the value is `undefined`;\n * - the key or entry is absent and would go into a flow mapping that has\n * members (`{ jira: A }`), which this writer does not add to;\n * - the key is written as an explicit `? key`;\n * - the result does not read back as written.\n */\nexport function spliceManifestValue(\n text: string,\n options: SpliceManifestOptions,\n): SplicedManifest {\n const { entry, key, value, file } = options;\n const join = options.join ?? PATH_JOIN;\n const at = (line?: number): string => {\n const name = file === undefined ? \"Manifest\" : `Manifest ${file}`;\n if (line === undefined) return name;\n return file === undefined ? `${name} line ${String(line)}` : `${name}:${String(line)}`;\n };\n\n if (key === FILE_SCHEMA_KEY) {\n throw new DocmetaError(\n `${at()}: refusing to write \"${FILE_SCHEMA_KEY}\" for \"${entry}\"; a manifest never chooses the schema a document is judged by. Use \"overrides\" in the config.`,\n );\n }\n if (value === undefined) {\n throw new DocmetaError(`${at()}: refusing to write \"${key}\" for \"${entry}\" with no value.`);\n }\n\n const eol = detectEol(text);\n const lc = new LineCounter();\n const doc = parseDocument(text, { lineCounter: lc, uniqueKeys: false });\n const problem = doc.errors[0];\n if (problem) {\n throw new DocmetaError(`${at()} is not valid YAML: ${problem.message}`);\n }\n const keyLine = (node: unknown): number | undefined => {\n const r = rangeOf(node);\n return r ? lc.linePos(r[0]).line : undefined;\n };\n const same =\n join === PATH_JOIN\n ? (a: string, b: string) => posix.normalize(a) === posix.normalize(b)\n : (a: string, b: string) => a === b;\n\n const root = doc.contents;\n let spelled = entry;\n let edit: Edit;\n if (root === null || (isScalar(root) && root.value === null && emptySource(text, root))) {\n edit = startManifest(text, entry, key, value, eol);\n } else if (!isMap(root)) {\n throw new DocmetaError(\n `${at()}: the manifest must be a mapping from document ${join === PATH_JOIN ? \"path\" : `\"${join}\"`} to owned keys.`,\n );\n } else {\n const style = detectStyle(text, root, eol);\n const matches = root.items.filter((p) => same(keyString(p.key), entry));\n const [first, second] = matches;\n if (first && second) {\n throw new DocmetaError(\n `${at(keyLine(second.key))}: \"${keyString(second.key)}\" is named twice (first at line ${String(keyLine(first.key) ?? \"?\")}). Merge the two entries into one.`,\n );\n }\n if (first === undefined) {\n if (root.flow === true && root.items.length > 0) {\n throw new DocmetaError(\n `${at()}: the manifest is a flow mapping ({ … }), which this writer does not add entries to. Rewrite it in block style.`,\n );\n }\n edit = appendEntry(text, root, entry, key, value, style);\n } else {\n spelled = keyString(first.key);\n const where = at(keyLine(first.key));\n const v = first.value;\n if (!isMap(v)) {\n throw new DocmetaError(`${where}: \"${spelled}\" must be a mapping of owned keys to values.`);\n }\n const hits = v.items.filter((kv) => keyString(kv.key) === key);\n const [hit, again] = hits;\n if (hit && again) {\n throw new DocmetaError(\n `${at(keyLine(again.key))}: \"${spelled}\" sets \"${key}\" twice (first at line ${String(keyLine(hit.key) ?? \"?\")}). Remove one.`,\n );\n }\n const flowRefusal = () =>\n new DocmetaError(\n `${where}: \"${spelled}\" is a flow mapping ({ … }), which this writer does not add keys to. Rewrite the entry in block style.`,\n );\n const formRefusal = () =>\n new DocmetaError(\n `${where}: \"${spelled}\" writes a key in a form this writer does not edit. Write it as \"${key}: …\".`,\n );\n // Each of these answers `undefined` for a shape it will not edit: a\n // flow mapping with members, or a key written as an explicit `? key`.\n let made: Edit | undefined;\n if (v.flow === true) {\n if (hit) made = replaceFlowValue(text, hit, value);\n else if (v.items.length === 0) made = fillEmptyEntry(text, first, key, value, style);\n else throw flowRefusal();\n if (!made) throw hit ? flowRefusal() : formRefusal();\n } else {\n made = hit\n ? replaceBlockValue(text, hit, value, style)\n : insertKey(text, v, key, value, style);\n if (!made) throw formRefusal();\n }\n edit = made;\n }\n }\n\n const out = text.slice(0, edit.start) + edit.insert + text.slice(edit.end);\n const line = readBack(doc, out, spelled, key, value, (why) =>\n new DocmetaError(\n `${at()}: writing \"${key}\" for \"${entry}\" did not read back as written, so nothing was written. ${why}`,\n ),\n );\n return { text: out, line };\n}\n\n/**\n * The value one document entry holds for one owned key, as the manifest text\n * stands. `undefined` when the entry or the key is absent, and for text that\n * is not a manifest at all.\n *\n * A writer that re-reads its target before replacing it needs this: it tells\n * the writer whether the entry it is about to rewrite is the one it read, or\n * one another process has changed since. Every refusal a malformed manifest\n * deserves is the splice's to raise, so this answers `undefined` rather than\n * throwing, and two `undefined`s compare equal.\n */\nexport function readManifestValue(\n text: string,\n options: { entry: string; key: string; join?: string },\n): unknown {\n const join = options.join ?? PATH_JOIN;\n const doc = parseDocument(text, { uniqueKeys: false });\n if (doc.errors.length > 0) return undefined;\n const root = doc.contents;\n if (!isMap(root)) return undefined;\n const same =\n join === PATH_JOIN\n ? (a: string, b: string) => posix.normalize(a) === posix.normalize(b)\n : (a: string, b: string) => a === b;\n const pair = root.items.find((p) => same(keyString(p.key), options.entry));\n const held = pair?.value;\n if (!isMap(held)) return undefined;\n const kv = held.items.find((p) => keyString(p.key) === options.key);\n const node = kv?.value;\n return isNode(node) ? (node.toJSON() as unknown) : undefined;\n}\n\n/**\n * Remove `options.key` from `options.entry` in the manifest `text`, and change\n * no other byte. An entry left with no keys goes too, since the loader refuses\n * an entry that is not a mapping, along with the blank line that spaced it.\n * A manifest, entry or key that is absent is left as it was.\n *\n * Throws `DocmetaError` where `spliceManifestValue` would: invalid YAML, a top\n * level or entry that is not a mapping, an entry named twice, a key set twice.\n * It also refuses a key in a flow mapping with other members, and a result\n * that does not read back with only that key gone.\n */\nexport function removeManifestKey(\n text: string,\n options: Omit<SpliceManifestOptions, \"value\">,\n): { text: string } {\n const { entry, key, file } = options;\n const join = options.join ?? PATH_JOIN;\n const at = (line?: number): string => {\n const name = file === undefined ? \"Manifest\" : `Manifest ${file}`;\n if (line === undefined) return name;\n return file === undefined ? `${name} line ${String(line)}` : `${name}:${String(line)}`;\n };\n\n const eol = detectEol(text);\n const lc = new LineCounter();\n const doc = parseDocument(text, { lineCounter: lc, uniqueKeys: false });\n const problem = doc.errors[0];\n if (problem) {\n throw new DocmetaError(`${at()} is not valid YAML: ${problem.message}`);\n }\n const keyLine = (node: unknown): number | undefined => {\n const r = rangeOf(node);\n return r ? lc.linePos(r[0]).line : undefined;\n };\n const root = doc.contents;\n if (root === null || (isScalar(root) && root.value === null)) return { text };\n if (!isMap(root)) {\n throw new DocmetaError(\n `${at()}: the manifest must be a mapping from document ${join === PATH_JOIN ? \"path\" : `\"${join}\"`} to owned keys.`,\n );\n }\n const same =\n join === PATH_JOIN\n ? (a: string, b: string) => posix.normalize(a) === posix.normalize(b)\n : (a: string, b: string) => a === b;\n const matches = root.items.filter((p) => same(keyString(p.key), entry));\n const [first, second] = matches;\n if (first && second) {\n throw new DocmetaError(\n `${at(keyLine(second.key))}: \"${keyString(second.key)}\" is named twice (first at line ${String(keyLine(first.key) ?? \"?\")}). Merge the two entries into one.`,\n );\n }\n if (first === undefined) return { text };\n const spelled = keyString(first.key);\n const where = at(keyLine(first.key));\n const v = first.value;\n if (!isMap(v)) {\n throw new DocmetaError(`${where}: \"${spelled}\" must be a mapping of owned keys to values.`);\n }\n const hits = v.items.filter((kv) => keyString(kv.key) === key);\n const [hit, again] = hits;\n if (hit && again) {\n throw new DocmetaError(\n `${at(keyLine(again.key))}: \"${spelled}\" sets \"${key}\" twice (first at line ${String(keyLine(hit.key) ?? \"?\")}). Remove one.`,\n );\n }\n if (hit === undefined) return { text };\n\n const whole = v.items.length === 1;\n if (!whole && v.flow === true) {\n throw new DocmetaError(\n `${where}: \"${spelled}\" is a flow mapping ({ … }), which this writer does not remove keys from. Rewrite the entry in block style.`,\n );\n }\n // The lines to cut: from the start of the key's line (the entry's, when\n // the entry goes) through the line break after the value's last line.\n const from = rangeOf(whole ? first.key : hit.key);\n const to = whole ? contentEnd(text, v) : (contentEnd(text, hit.value) ?? contentEnd(text, hit.key));\n if (!from || to === undefined) {\n throw new DocmetaError(\n `${where}: \"${spelled}\" writes a key in a form this writer does not edit. Write it as \"${key}: …\".`,\n );\n }\n let { start, end } = keyLines(text, from[0], to, eol);\n if (whole) {\n // The blank line that spaced the entry from the one before goes with it;\n // for a first entry, the one after it does.\n if (text.slice(start - 2 * eol.length, start) === eol + eol) start -= eol.length;\n else if (start === 0 && text.startsWith(eol, end)) end += eol.length;\n }\n const out = text.slice(0, start) + text.slice(end);\n\n const after = parseDocument(out, { uniqueKeys: false });\n const fail = (why: string) =>\n new DocmetaError(\n `${at()}: removing \"${key}\" for \"${entry}\" did not read back as removed, so nothing was written. ${why}`,\n );\n if (after.errors[0]) throw fail(`The result is not valid YAML: ${after.errors[0].message}`);\n const was: unknown = doc.toJS({ maxAliasCount: 100 });\n const wasRoot = isRecord(was) ? was : {};\n const wasEntry = wasRoot[spelled];\n const rest = Object.fromEntries(\n Object.entries(isRecord(wasEntry) ? wasEntry : {}).filter(([k]) => k !== key),\n );\n const kept = Object.entries(wasRoot).filter(([k]) => k !== spelled);\n if (Object.keys(rest).length > 0) kept.push([spelled, rest]);\n const now: unknown = after.toJS({ maxAliasCount: 100 });\n const expected = kept.length === 0 ? null : Object.fromEntries(kept);\n if (!deepEqual(now ?? null, expected)) throw fail(\"Another value in the manifest would have changed.\");\n return { text: out };\n}\n\n/**\n * Rename the document entry `options.entry` to `options.to` in the manifest\n * `text`, and change no other byte: only the entry's key is replaced, so its\n * values, comments and position stay. `meta query` uses it when a `_path`\n * move renames a document a path-joined manifest names (proposal 0047). A\n * manifest or entry that is absent is left as it was.\n *\n * Throws `DocmetaError` where `spliceManifestValue` would (invalid YAML, a top\n * level that is not a mapping, an entry named twice), when `to` already has\n * an entry, for a key written as an explicit `? key`, and for a result that\n * does not read back with only the entry's name changed.\n */\nexport function renameManifestEntry(\n text: string,\n options: { entry: string; to: string; join?: string; file?: string },\n): { text: string } {\n const { entry, to, file } = options;\n const join = options.join ?? PATH_JOIN;\n const at = (line?: number): string => {\n const name = file === undefined ? \"Manifest\" : `Manifest ${file}`;\n if (line === undefined) return name;\n return file === undefined ? `${name} line ${String(line)}` : `${name}:${String(line)}`;\n };\n const lc = new LineCounter();\n const doc = parseDocument(text, { lineCounter: lc, uniqueKeys: false });\n const problem = doc.errors[0];\n if (problem) {\n throw new DocmetaError(`${at()} is not valid YAML: ${problem.message}`);\n }\n const keyLine = (node: unknown): number | undefined => {\n const r = rangeOf(node);\n return r ? lc.linePos(r[0]).line : undefined;\n };\n const root = doc.contents;\n if (root === null || (isScalar(root) && root.value === null)) return { text };\n if (!isMap(root)) {\n throw new DocmetaError(\n `${at()}: the manifest must be a mapping from document ${join === PATH_JOIN ? \"path\" : `\"${join}\"`} to owned keys.`,\n );\n }\n const same =\n join === PATH_JOIN\n ? (a: string, b: string) => posix.normalize(a) === posix.normalize(b)\n : (a: string, b: string) => a === b;\n const [first, second] = root.items.filter((p) => same(keyString(p.key), entry));\n if (first && second) {\n throw new DocmetaError(\n `${at(keyLine(second.key))}: \"${keyString(second.key)}\" is named twice (first at line ${String(keyLine(first.key) ?? \"?\")}). Merge the two entries into one.`,\n );\n }\n if (first === undefined) return { text };\n const taken = root.items.find((p) => same(keyString(p.key), to));\n if (taken !== undefined) {\n throw new DocmetaError(\n `${at(keyLine(taken.key))}: \"${keyString(taken.key)}\" already has an entry, so \"${keyString(first.key)}\" cannot be renamed to it. Merge the two entries into one.`,\n );\n }\n const spelled = keyString(first.key);\n const r = rangeOf(first.key);\n const end = contentEnd(text, first.key);\n if (!r || end === undefined || colonEnd(text, first) === undefined) {\n throw new DocmetaError(\n `${at(keyLine(first.key))}: \"${spelled}\" is written in a form this writer does not edit. Write it as \"${spelled}: …\".`,\n );\n }\n const quoted = isScalar(first.key) && (first.key.type === \"QUOTE_DOUBLE\" || first.key.type === \"QUOTE_SINGLE\");\n const plain = stringify(to, { lineWidth: 0 }).replace(/\\n$/, \"\");\n const insert = quoted || plain.includes(\"\\n\") ? JSON.stringify(to) : plain;\n const out = text.slice(0, r[0]) + insert + text.slice(end);\n\n const after = parseDocument(out, { uniqueKeys: false });\n const fail = (why: string) =>\n new DocmetaError(\n `${at()}: renaming \"${spelled}\" to \"${to}\" did not read back as renamed, so nothing was written. ${why}`,\n );\n if (after.errors[0]) throw fail(`The result is not valid YAML: ${after.errors[0].message}`);\n const was: unknown = doc.toJS({ maxAliasCount: 100 });\n const wasRoot = isRecord(was) ? was : {};\n const expected = Object.fromEntries(\n Object.entries(wasRoot).map(([k, v]) => [k === spelled ? to : k, v]),\n );\n const now: unknown = after.toJS({ maxAliasCount: 100 });\n if (!deepEqual(now, expected)) throw fail(\"Another value in the manifest would have changed.\");\n return { text: out };\n}\n\n/** An empty manifest (no text, only comments, or a bare `---`): the first entry. */\nfunction startManifest(text: string, entry: string, key: string, value: unknown, eol: string): Edit {\n const style: Style = { step: 2, indentSeq: true, eol };\n const block = blockLines({ [entry]: { [key]: value } }, 0, style);\n let insert: string;\n if (text === \"\" || text.endsWith(\"\\n\")) insert = block + eol;\n else insert = eol + block;\n return { start: text.length, end: text.length, insert };\n}\n\n/** A new entry after the last one, or in place of an empty `{}` manifest. */\nfunction appendEntry(\n text: string,\n root: YAMLMap,\n entry: string,\n key: string,\n value: unknown,\n style: Style,\n): Edit {\n const body = { [entry]: { [key]: value } };\n if (root.flow === true) {\n // `{}` and nothing else: the refusal for a flow mapping with members ran first.\n const r = rangeOf(root);\n const start = r ? r[0] : text.length;\n const end = contentEnd(text, root) ?? start;\n return { start, end, insert: blockLines(body, colOf(text, start), style) };\n }\n const firstKey = rangeOf(root.items[0]?.key);\n const col = firstKey ? colOf(text, firstKey[0]) : 0;\n const pos = lineEnd(text, contentEnd(text, root) ?? text.length);\n const last = root.items.at(-1);\n const spaced =\n root.items.length > 1 && isNode(last?.key) && last.key.spaceBefore === true;\n return {\n start: pos,\n end: pos,\n insert: style.eol + (spaced ? style.eol : \"\") + blockLines(body, col, style),\n };\n}\n\n/** `docs/a.md: {}`: the empty flow mapping becomes a block one holding the key. */\nfunction fillEmptyEntry(\n text: string,\n entryPair: Pair,\n key: string,\n value: unknown,\n style: Style,\n): Edit | undefined {\n const start = colonEnd(text, entryPair);\n const keyRange = rangeOf(entryPair.key);\n const end = contentEnd(text, entryPair.value);\n if (start === undefined || !keyRange || end === undefined) return undefined;\n const col = colOf(text, keyRange[0]) + style.step;\n return { start, end, insert: style.eol + blockLines({ [key]: value }, col, style) };\n}\n\n/**\n * Re-parse `out` and check it says what was asked: the entry's key deep-equals\n * `value`, and every other value is what it was. Returns the value's line.\n */\nfunction readBack(\n before: Document,\n out: string,\n spelled: string,\n key: string,\n value: unknown,\n fail: (why: string) => DocmetaError,\n): number {\n const lc = new LineCounter();\n const after = parseDocument(out, { lineCounter: lc, uniqueKeys: false });\n const problem = after.errors[0];\n if (problem) throw fail(`The result is not valid YAML: ${problem.message}`);\n\n const was: unknown = before.toJS({ maxAliasCount: 100 });\n const now: unknown = after.toJS({ maxAliasCount: 100 });\n const wasRoot = isRecord(was) ? was : {};\n const wasEntry = wasRoot[spelled];\n const expected = {\n ...wasRoot,\n [spelled]: { ...(isRecord(wasEntry) ? wasEntry : {}), [key]: value },\n };\n const nowEntry = isRecord(now) ? now[spelled] : undefined;\n if (!isRecord(nowEntry) || !deepEqual(nowEntry[key], value)) {\n throw fail(\n \"The value reads back differently. A Date, an undefined member, or another value YAML cannot hold does not survive the trip.\",\n );\n }\n if (!deepEqual(now, expected)) {\n throw fail(\"Another value in the manifest would have changed.\");\n }\n\n const root = after.contents;\n const pair = isMap(root) ? root.items.find((p) => keyString(p.key) === spelled) : undefined;\n const entryMap = pair?.value;\n const kv = isMap(entryMap) ? entryMap.items.find((p) => keyString(p.key) === key) : undefined;\n const r = rangeOf(kv?.value) ?? rangeOf(kv?.key);\n if (!r) throw fail(\"The written value could not be found again.\");\n return lc.linePos(r[0]).line;\n}\n\nfunction isRecord(x: unknown): x is Record<string, unknown> {\n return typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n","/**\n * `provenance`, derived (proposal 0046 § The derivation contract): which body\n * lines a machine wrote, read from `git blame --line-porcelain` and the\n * commits it names, compared with the pins a page already carries.\n *\n * Pure functions over parsed inputs. Running blame, reading commit messages\n * and reading blobs at a commit is the git source's job (`git.ts`); nothing\n * here spawns a process or touches the filesystem.\n *\n * The reference implementation is `docs/proposals/0046/ladders/blame-examples.cjs`.\n * Every rule its `RESOLVED` notes decide is carried here, and the test suite\n * runs the ladder beside this module so the two cannot drift apart.\n *\n * Two numberings meet here. Entries store BODY lines, counted from the first\n * line after the frontmatter, so writing the stamp never moves its own pins.\n * Everything a person reads — a range on the command line, a report, a\n * finding — is FILE lines, and the conversion happens at that edge.\n */\nimport picomatch from \"picomatch\";\nimport { extractFrontmatter, locateFrontmatter } from \"../../extractors/frontmatter.js\";\nimport { DocmetaError, type FieldError } from \"../../types.js\";\nimport {\n LineRangeError,\n findWindows,\n lineSpec,\n parseLines,\n pinOfLines,\n spellLines,\n splitLines,\n splitPageArgument,\n toBodyLines,\n toFileLines,\n type LineSpec,\n type PageLines,\n} from \"../../../shared/pin.js\";\nimport { DERIVED_KEYWORD, DERIVED_STALE_SCHEMA } from \"./types.js\";\n\n/**\n * The sha blame reports for a line that is not committed yet, in a SHA-1\n * repository. A SHA-256 repository reports 64 zeros; `parseLinePorcelain`\n * reads any all-zero sha as uncommitted.\n */\nexport const ZERO_SHA = \"0000000000000000000000000000000000000000\";\n\n/** `derive.machines` when the config does not set it: 0040's `[bot]` suffix. */\nexport const DEFAULT_MACHINES: readonly string[] = [\"*[bot]\"];\n\n/** The instance path every provenance finding carries. */\nconst PROVENANCE_POINTER = \"/provenance\";\n\n/**\n * Whether a line is blank: empty, or whitespace only. A blank line carries no\n * authorship (proposal 0071). It has no evidence, never starts or ends a\n * range, and never splits one: blank lines between two lines of one machine\n * sit inside its range, and its pin covers them.\n */\nexport function isBlankLine(line: string | undefined): boolean {\n return (line ?? \"\").trim() === \"\";\n}\n\n/** A span with its blank edge lines trimmed, or undefined when every line is blank. */\nfunction trimBlank(body: readonly string[], span: PageLines): PageLines | undefined {\n let { start, end } = span;\n while (start <= end && isBlankLine(body[start - 1])) start++;\n while (end >= start && isBlankLine(body[end - 1])) end--;\n return start > end ? undefined : { start, end };\n}\n\n/** Why a span is not a well-formed range: it holds only blank lines, or its first line, its last, or both are blank. */\nexport type BlankEdges = \"only\" | \"start\" | \"end\" | \"both\";\n\nfunction blankEdges(body: readonly string[], span: PageLines): BlankEdges | undefined {\n const first = isBlankLine(body[span.start - 1]);\n const last = isBlankLine(body[span.end - 1]);\n if (!first && !last) return undefined;\n if (trimBlank(body, span) === undefined) return \"only\";\n return first && last ? \"both\" : first ? \"start\" : \"end\";\n}\n\n// ---------------------------------------------------------------------------\n// Entries and pages\n// ---------------------------------------------------------------------------\n\n/** One `provenance` entry as stored: body lines, and the pin over them. */\nexport interface ProvenanceEntry {\n \"generated-by\": string;\n lines: LineSpec;\n integrity: string;\n}\n\nconst PLAIN_PIN = /^sha256-[0-9a-f]{64}$/;\n\n/**\n * The well-formed entries of a `provenance` value, in order. An entry the\n * schema would reject for its three keys (no machine, unreadable lines, a pin\n * that is not `sha256-`) is neither evidence nor compared: the schema finding\n * speaks for it. A key outside the closed set does not make an entry\n * unreadable. The schema reports that key, and the entry keeps it, so a write\n * that keeps the entry does not delete it silently.\n */\nexport function provenanceEntries(value: unknown): ProvenanceEntry[] {\n if (!Array.isArray(value)) return [];\n const out: ProvenanceEntry[] = [];\n for (const item of value as unknown[]) {\n if (typeof item !== \"object\" || item === null || Array.isArray(item)) continue;\n const record = item as Record<string, unknown>;\n const machine = record[\"generated-by\"];\n const lines = record.lines;\n const integrity = record.integrity;\n if (typeof machine !== \"string\" || machine === \"\") continue;\n if (typeof lines !== \"string\" && typeof lines !== \"number\") continue;\n if (parseLines(lines) === undefined) continue;\n if (typeof integrity !== \"string\" || !PLAIN_PIN.test(integrity)) continue;\n out.push({ ...record, \"generated-by\": machine, lines, integrity });\n }\n return out;\n}\n\n/** A page read for provenance. */\nexport interface ProvenancePage {\n /** Every normalized line of the file. */\n lines: string[];\n /** The file line body line 1 sits on. */\n bodyLine: number;\n /** The body's lines: `lines` from `bodyLine` on. */\n body: string[];\n /** The well-formed `provenance` entries the frontmatter carries. */\n stamp: ProvenanceEntry[];\n}\n\nexport interface ReadPageOptions {\n /**\n * Whether the page's metadata is a leading fenced block. Default true. A\n * page whose metadata is part of the body (html, xml, dita) has body line 1\n * at file line 1 and carries no stamp of its own; its record lives in a\n * manifest.\n */\n fenced?: boolean;\n}\n\n/**\n * Split a page into its body and its stamp. The frontmatter is the block\n * `validate` reads; one that does not parse carries no stamp, and its body\n * still starts after it.\n */\nexport function readProvenancePage(content: string, opts?: ReadPageOptions): ProvenancePage {\n const lines = splitLines(content);\n const loc = opts?.fenced === false ? null : locateFrontmatter(content);\n if (loc === null) return { lines, bodyLine: 1, body: lines, stamp: [] };\n const head = content.slice(0, loc.closeEnd);\n const newlines = head.split(\"\\n\").length - 1;\n // The body starts on the line after the block, and one line further when\n // the file ends at the closing fence with no newline after it.\n const bodyLine = newlines + (head.endsWith(\"\\n\") ? 1 : 2);\n let stamp: ProvenanceEntry[] = [];\n try {\n stamp = provenanceEntries(extractFrontmatter(content, \"markdown\").data.provenance);\n } catch {\n stamp = [];\n }\n return { lines, bodyLine, body: lines.slice(bodyLine - 1), stamp };\n}\n\n// ---------------------------------------------------------------------------\n// git blame --line-porcelain\n// ---------------------------------------------------------------------------\n\n/** One final line of `git blame --line-porcelain`. */\nexport interface BlameLine {\n sha: string;\n /** The line's number in the commit that last changed it. */\n origLine: number;\n /** The line's number in the working file. */\n finalLine: number;\n /** Lines in this group; blame writes it on a group's first line only. */\n groupCount?: number;\n author: string;\n /** `author-mail` without its angle brackets. */\n authorMail: string;\n filename: string;\n /** `previous <sha> <filename>`, when blame reports one. */\n previous?: { sha: string; filename: string };\n /** The commit is a boundary of the blamed history (a root, or a `--since` edge). */\n boundary: boolean;\n /** The zero sha: a line not committed yet. */\n uncommitted: boolean;\n /** The line as the working file holds it, a CR included. */\n content: string;\n}\n\n/** A SHA-1 sha is 40 hex digits, and a SHA-256 repository's (`objectFormat=sha256`) is 64. */\nconst HEADER = /^([0-9a-f]{40}(?:[0-9a-f]{24})?) ([1-9][0-9]*) ([1-9][0-9]*)(?: ([1-9][0-9]*))?$/;\nconst ALL_ZERO = /^0+$/;\n\n/**\n * Parse `git blame --line-porcelain`. Throws a plain `Error` on anything\n * else, plain `--porcelain` included: that form writes a group's header once,\n * and a line without its header cannot be attributed. Both are the caller's\n * bug, never the user's.\n */\nexport function parseLinePorcelain(text: string): BlameLine[] {\n const rows = text.split(\"\\n\");\n if (rows.length > 0 && rows[rows.length - 1] === \"\") rows.pop();\n const out: BlameLine[] = [];\n let i = 0;\n while (i < rows.length) {\n const headerRow = rows[i] ?? \"\";\n const m = HEADER.exec(headerRow);\n const sha = m?.[1];\n const orig = m?.[2];\n const final = m?.[3];\n if (sha === undefined || orig === undefined || final === undefined) {\n throw new Error(`porcelain: expected a header at row ${i + 1}, got ${JSON.stringify(headerRow)}`);\n }\n const finalLine = Number(final);\n const count = m?.[4];\n const fields = new Map<string, string | true>();\n i++;\n for (let row = rows[i]; row !== undefined && !row.startsWith(\"\\t\"); row = rows[i]) {\n const space = row.indexOf(\" \");\n if (space === -1) fields.set(row, true);\n else fields.set(row.slice(0, space), row.slice(space + 1));\n i++;\n }\n const contentRow = rows[i];\n if (contentRow === undefined) throw new Error(`porcelain: line ${finalLine} has no content row`);\n const author = fields.get(\"author\");\n const filename = fields.get(\"filename\");\n if (typeof author !== \"string\" || typeof filename !== \"string\") {\n throw new Error(`porcelain: line ${finalLine} has no full header; run blame with --line-porcelain`);\n }\n const mail = fields.get(\"author-mail\");\n const previous = fields.get(\"previous\");\n const space = typeof previous === \"string\" ? previous.indexOf(\" \") : -1;\n out.push({\n sha,\n origLine: Number(orig),\n finalLine,\n ...(count !== undefined ? { groupCount: Number(count) } : {}),\n author,\n authorMail: typeof mail === \"string\" ? mail.replace(/^<(.*)>$/, \"$1\") : \"\",\n filename,\n ...(typeof previous === \"string\" && space !== -1\n ? { previous: { sha: previous.slice(0, space), filename: previous.slice(space + 1) } }\n : {}),\n boundary: fields.get(\"boundary\") === true,\n uncommitted: ALL_ZERO.test(sha),\n content: contentRow.slice(1),\n });\n i++;\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Evidence, per body line\n// ---------------------------------------------------------------------------\n\n/** What one commit offers as evidence. */\nexport interface CommitEvidence {\n sha: string;\n /** Trailer values by kind, in message order. `collectTrailers` builds it from key/value pairs. */\n trailers: { generatedBy: string[]; coAuthoredBy: string[] };\n /** The page's full text at this commit; rule 2 is skipped without it. */\n blob?: string;\n /**\n * The `provenance` entries recorded at this commit, when the record lives\n * in a manifest (read from the manifest's blob at this commit, under the\n * page's path). Absent means the page's own frontmatter in `blob`.\n */\n stamp?: readonly ProvenanceEntry[];\n}\n\n/**\n * Trailer pairs sorted into the two kinds evidence reads. Keys compare\n * without case, as git's own trailer parsing does; values are trimmed and\n * keep message order.\n */\nexport function collectTrailers(pairs: readonly (readonly [string, string])[]): CommitEvidence[\"trailers\"] {\n const trailers: CommitEvidence[\"trailers\"] = { generatedBy: [], coAuthoredBy: [] };\n for (const [key, value] of pairs) {\n const k = key.toLowerCase();\n if (k === \"generated-by\") trailers.generatedBy.push(value.trim());\n else if (k === \"co-authored-by\") trailers.coAuthoredBy.push(value.trim());\n }\n return trailers;\n}\n\n/** Which of 0046's five evidence rules answered for a line. */\nexport type EvidenceRule = 1 | 2 | 3 | 4 | 5;\n\n/** A line's evidence: the machine, or none under rule 5, and the blamed sha. */\nexport interface LineEvidence {\n machine?: string;\n rule: EvidenceRule;\n sha: string;\n}\n\nconst IDENTITY_GLOB = { literalBrackets: true, dot: true, bash: true } as const;\n\n/**\n * The machine a `Name <email>` trailer value names, when its name or its\n * email matches a `derive.machines` glob; undefined for a person. Globs are\n * picomatch's, case-sensitive, with literal brackets, so `*[bot]` is a name\n * ending in `[bot]` and not \"anything ending in b, o or t\" (stress test 16).\n * An identity is not a path: `dot` and `bash` let `*` cross a `/` and match a\n * leading `.`, so `ci/deploy[bot]` and `.hidden[bot]` are machines, as\n * `endsWith(\"[bot]\")` had them. The machine is the name as written, and the\n * email only when the name is empty.\n */\nexport function machineIdentity(value: string, machines: readonly string[]): string | undefined {\n const m = /^(.*?)\\s*<([^>]*)>\\s*$/.exec(value);\n const name = m === null ? value.trim() : (m[1] ?? \"\");\n const email = m === null ? \"\" : (m[2] ?? \"\");\n const match = (s: string): boolean =>\n s !== \"\" && machines.some((glob) => picomatch.isMatch(s, glob, IDENTITY_GLOB));\n if (!match(name) && !match(email)) return undefined;\n return name !== \"\" ? name : email;\n}\n\n/** What evidence resolution holds constant across a page. */\nexport interface EvidenceContext {\n commits: ReadonlyMap<string, CommitEvidence>;\n machines: readonly string[];\n /** `--generated-by`, or `MANNI_GENERATED_BY`; empty counts as unset. */\n generatedBy?: string;\n /** Whether the page's metadata is fenced, for reading commit blobs. Default true. */\n fenced?: boolean;\n}\n\n/**\n * Rule 2: the machine a verified stamp at the commit names for the line's\n * number there. The orig line is converted to that blob's own body\n * numbering, since the commit's frontmatter need not be today's. A stamp is\n * checked only at its recorded lines, so the same text elsewhere in the blob\n * does not count, and the first covering entry that verifies wins.\n */\nfunction stampEvidence(commit: CommitEvidence, origLine: number, fenced: boolean | undefined): string | undefined {\n const stamps = verifiedStamps(commit, fenced);\n if (stamps === undefined) return undefined;\n const body = origLine - stamps.bodyLine + 1;\n if (body < 1) return undefined;\n return stamps.entries.find((entry) => body >= entry.start && body <= entry.end)?.generatedBy;\n}\n\n/**\n * Whether a commit carries the page's provenance stamp (proposal 0069, rule\n * 3): at least one entry of its stamp verifies against the page at that\n * commit. Such a commit is the whole account of the lines it last touched.\n */\nfunction carriesStamp(commit: CommitEvidence, fenced: boolean | undefined): boolean {\n return (verifiedStamps(commit, fenced)?.entries.length ?? 0) > 0;\n}\n\n/** The stamp entries that verify against the page at one commit, in stamp order. */\ninterface VerifiedStamps {\n /** The file line body line 1 sits on, in the commit's blob. */\n bodyLine: number;\n entries: { start: number; end: number; generatedBy: string }[];\n}\n\n/**\n * A commit's stamp, read and verified once. Every line a commit last touched\n * asks it, and reading means parsing the blob's frontmatter and hashing each\n * stamped range, so asking per line re-did both for every line.\n */\nfunction verifiedStamps(commit: CommitEvidence, fenced: boolean | undefined): VerifiedStamps | undefined {\n if (commit.blob === undefined) return undefined;\n const memo = fenced === false ? stampsUnfenced : stampsFenced;\n const known = memo.get(commit);\n if (known !== undefined) return known;\n const page = readProvenancePage(commit.blob, fenced === undefined ? undefined : { fenced });\n const entries: VerifiedStamps[\"entries\"] = [];\n for (const entry of commit.stamp === undefined ? page.stamp : provenanceEntries(commit.stamp)) {\n const span = parseLines(entry.lines);\n if (span !== undefined && pinOfLines(page.body, span) === entry.integrity) {\n entries.push({ start: span.start, end: span.end, generatedBy: entry[\"generated-by\"] });\n }\n }\n const stamps = { bodyLine: page.bodyLine, entries };\n memo.set(commit, stamps);\n return stamps;\n}\n\n/**\n * `verifiedStamps` per commit. Keyed by identity: a run builds its\n * CommitEvidence objects fresh, so an entry never outlives the evidence it\n * describes. A pool of reused objects would need this cleared between runs.\n * One map per fenced setting, since the answer reads the commit's blob as\n * fenced or not: a commit shared by a Markdown page and an HTML page is\n * judged once for each.\n */\nconst stampsFenced = new WeakMap<CommitEvidence, VerifiedStamps>();\nconst stampsUnfenced = new WeakMap<CommitEvidence, VerifiedStamps>();\n\n/**\n * Rules 2 to 4 for one line. An uncommitted line has no commit, so none of\n * them applies to it; in particular the working tree's own stamp is never\n * evidence for itself. A stamp outranks its own commit's trailers, because\n * the stamp names lines and a trailer names a commit. And a commit that\n * carries a verified stamp is the whole account of its lines (proposal 0069,\n * rule 3): a line outside every stamped range has no evidence, so a trailer\n * a squash appended cannot turn a line the branch left unstamped into a\n * machine's.\n */\nfunction recordedEvidence(line: BlameLine, ctx: EvidenceContext): LineEvidence {\n if (line.uncommitted) return { rule: 5, sha: line.sha };\n const commit = ctx.commits.get(line.sha);\n if (commit === undefined) throw new Error(`no commit ${line.sha}`);\n const stamped = stampEvidence(commit, line.origLine, ctx.fenced);\n if (stamped !== undefined) return { machine: stamped, rule: 2, sha: line.sha };\n if (carriesStamp(commit, ctx.fenced)) return { rule: 5, sha: line.sha };\n const generated = commit.trailers.generatedBy.map((v) => v.trim()).find((v) => v !== \"\");\n if (generated !== undefined) return { machine: generated, rule: 3, sha: line.sha };\n for (const value of commit.trailers.coAuthoredBy) {\n const machine = machineIdentity(value.trim(), ctx.machines);\n if (machine !== undefined) return { machine, rule: 4, sha: line.sha };\n }\n return { rule: 5, sha: line.sha };\n}\n\n/** All five evidence rules for one blamed line, first match wins. */\nexport function resolveLineEvidence(line: BlameLine, ctx: EvidenceContext): LineEvidence {\n if (line.uncommitted && ctx.generatedBy !== undefined && ctx.generatedBy !== \"\") {\n return { machine: ctx.generatedBy, rule: 1, sha: line.sha };\n }\n return recordedEvidence(line, ctx);\n}\n\n// ---------------------------------------------------------------------------\n// Derivation\n// ---------------------------------------------------------------------------\n\n/** One derived range: its entry, its body lines, and its first line's evidence. */\nexport interface DerivedRange {\n entry: ProvenanceEntry;\n span: PageLines;\n evidence: LineEvidence;\n}\n\n/** A page's derivation: the page, each body line's evidence, and the ranges. */\nexport interface ProvenanceDerivation {\n page: ProvenancePage;\n evidenceByLine: ReadonlyMap<number, LineEvidence>;\n derived: DerivedRange[];\n}\n\nexport interface DeriveProvenanceInput {\n /** The page's working text. */\n content: string;\n blame: readonly BlameLine[];\n commits: ReadonlyMap<string, CommitEvidence>;\n /** `derive.machines`; `DEFAULT_MACHINES` when absent. */\n machines?: readonly string[];\n generatedBy?: string;\n fenced?: boolean;\n}\n\n/** The pin of a span known to lie inside `lines`. */\nfunction pinOf(lines: readonly string[], span: PageLines): string {\n const pin = pinOfLines(lines, span);\n if (pin === undefined) throw new Error(`provenance: lines ${spellLines(span)} fall outside the body`);\n return pin;\n}\n\nfunction contextOf(input: Omit<DeriveProvenanceInput, \"content\" | \"blame\">): EvidenceContext {\n return {\n commits: input.commits,\n machines: input.machines ?? DEFAULT_MACHINES,\n ...(input.generatedBy !== undefined ? { generatedBy: input.generatedBy } : {}),\n ...(input.fenced !== undefined ? { fenced: input.fenced } : {}),\n };\n}\n\nfunction readOptions(fenced: boolean | undefined): ReadPageOptions | undefined {\n return fenced === undefined ? undefined : { fenced };\n}\n\n/**\n * Derive a page's `provenance`: resolve every non-blank body line, then group\n * the lines resolved to one machine into one entry, pinned over the current\n * body. A blank line has no evidence and neither opens nor closes a group, so\n * a range starts and ends on a non-blank line and spans the blank lines\n * between two of its machine's lines (proposal 0071).\n */\nexport function deriveProvenance(input: DeriveProvenanceInput): ProvenanceDerivation {\n const page = readProvenancePage(input.content, readOptions(input.fenced));\n const ctx = contextOf(input);\n const evidenceByLine = new Map<number, LineEvidence>();\n for (const line of input.blame) {\n const body = line.finalLine - page.bodyLine + 1;\n if (body < 1) continue; // a frontmatter line\n if (isBlankLine(page.body[body - 1])) continue;\n evidenceByLine.set(body, resolveLineEvidence(line, ctx));\n }\n const groups: { machine: string; start: number; end: number; first: LineEvidence }[] = [];\n let open: (typeof groups)[number] | undefined;\n for (let n = 1; n <= page.body.length; n++) {\n if (isBlankLine(page.body[n - 1])) continue;\n const evidence = evidenceByLine.get(n);\n const machine = evidence?.machine;\n // Only blank lines lie between the open group's end and n: any other\n // line would have closed it.\n if (open !== undefined && machine !== undefined && machine === open.machine) {\n open.end = n;\n continue;\n }\n if (open !== undefined) groups.push(open);\n open = machine === undefined || evidence === undefined ? undefined : { machine, start: n, end: n, first: evidence };\n }\n if (open !== undefined) groups.push(open);\n return {\n page,\n evidenceByLine,\n derived: groups.map((g) => {\n const span = { start: g.start, end: g.end };\n return {\n entry: { \"generated-by\": g.machine, lines: lineSpec(span), integrity: pinOf(page.body, span) },\n span,\n evidence: g.first,\n };\n }),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Comparison\n// ---------------------------------------------------------------------------\n\n/** 0046's comparison verdicts. */\nexport type ProvenanceStatus = \"current\" | \"moved\" | \"changed\" | \"stale\" | \"unset\";\n\n/**\n * One range's verdict. `entry` is the stamped entry, or the derived one for\n * `unset`. `span` is where its text is now in body lines, and the recorded\n * lines for `changed`. `evidence` is the contradicting line's for `stale` and\n * the range's first line's for `unset`. `noEvidence` marks a current or moved\n * range no line of which names a machine. `blank` marks a stale entry whose\n * text holds, at `span`, but starts or ends on a blank line (proposal 0071).\n */\nexport interface ProvenanceComparison {\n status: ProvenanceStatus;\n entry: ProvenanceEntry;\n span: PageLines;\n evidence?: LineEvidence;\n noEvidence?: true;\n blank?: BlankEdges;\n}\n\n/**\n * The candidate nearest the recorded lines (stress test 12): distance is\n * between start lines, and an equal distance goes to the earlier candidate.\n */\nfunction nearest<T extends { span: PageLines }>(candidates: readonly T[], recorded: PageLines): T | undefined {\n let best: { c: T; d: number } | undefined;\n for (const c of candidates) {\n const d = Math.abs(c.span.start - recorded.start);\n if (best === undefined || d < best.d || (d === best.d && c.span.start < best.c.span.start)) best = { c, d };\n }\n return best?.c;\n}\n\nconst sameSpan = (a: PageLines, b: PageLines): boolean => a.start === b.start && a.end === b.end;\n\n/**\n * What the evidence over a span says about a stamp's machine: the first line\n * that names a different machine, and whether any line names a machine.\n */\nfunction scanEvidence(\n evidenceByLine: ReadonlyMap<number, LineEvidence>,\n span: PageLines,\n machine: string,\n): { contradiction?: LineEvidence; anyMachine: boolean } {\n let anyMachine = false;\n for (let n = span.start; n <= span.end; n++) {\n const evidence = evidenceByLine.get(n);\n if (evidence?.machine === undefined) continue;\n anyMachine = true;\n if (evidence.machine !== machine) return { contradiction: evidence, anyMachine };\n }\n return { anyMachine };\n}\n\n/**\n * Compare a page's stamped entries with a fresh derivation: one result per\n * well-formed stamped entry, in order, then one `unset` per derived range\n * nothing covers.\n *\n * The recorded lines first: when the pin holds there and no line there names\n * a different machine, the entry is current, and it claims only a derived\n * range over exactly those lines. The same text elsewhere, even another\n * machine's, is not this entry's.\n *\n * Otherwise by integrity: an unclaimed derived range with the stamp's pin,\n * nearest by lines. The same machine is current at the recorded lines and\n * moved elsewhere; another machine is stale. Each derived range is taken once.\n *\n * Otherwise the pin is searched for across the whole body, nearest window\n * first. Found nowhere, it is changed. Found, it is stale when a line of the\n * window names a different machine, and current or moved otherwise: lines\n * that name the stamp's machine or no machine are not a contradiction.\n *\n * An entry whose text holds but starts or ends on a blank line, a blank-only\n * one included, is not a well-formed range (proposal 0071): it is stale where\n * its text is, and `blank` says why.\n *\n * A derived range is unset when some non-blank line of it lies outside every\n * span a result above holds, which for a changed entry is its recorded lines.\n * A person's edit inside an agent's range is therefore one changed finding,\n * not a changed finding and two unset ones. A blank line is never unset, so\n * entries a derived range spans across a blank line leave it covered.\n */\nexport function compareProvenance(\n stamped: readonly ProvenanceEntry[],\n derivation: ProvenanceDerivation,\n): ProvenanceComparison[] {\n const { page, evidenceByLine, derived } = derivation;\n const claimed = new Set<DerivedRange>();\n const results: ProvenanceComparison[] = [];\n for (const entry of provenanceEntries(stamped)) {\n const recorded = parseLines(entry.lines);\n if (recorded === undefined) continue; // unreachable: provenanceEntries checked it\n const machine = entry[\"generated-by\"];\n\n const takenHere = [...claimed].some((d) => sameSpan(d.span, recorded));\n if (!takenHere && pinOfLines(page.body, recorded) === entry.integrity) {\n const here = scanEvidence(evidenceByLine, recorded, machine);\n const blank = blankEdges(page.body, recorded);\n if (here.contradiction === undefined && blank !== undefined) {\n results.push({ status: \"stale\", entry, span: recorded, blank });\n continue;\n }\n if (here.contradiction === undefined) {\n const exact = derived.find(\n (d) => !claimed.has(d) && sameSpan(d.span, recorded) && d.entry.integrity === entry.integrity,\n );\n if (exact !== undefined) claimed.add(exact);\n results.push({ status: \"current\", entry, span: recorded, ...(here.anyMachine ? {} : { noEvidence: true as const }) });\n continue;\n }\n }\n\n const pool = derived.filter((d) => !claimed.has(d) && d.entry.integrity === entry.integrity);\n const hit = nearest(pool, recorded);\n if (hit !== undefined) {\n claimed.add(hit);\n if (hit.entry[\"generated-by\"] !== machine) {\n results.push({ status: \"stale\", entry, span: hit.span, evidence: hit.evidence });\n } else {\n results.push({ status: sameSpan(hit.span, recorded) ? \"current\" : \"moved\", entry, span: hit.span });\n }\n continue;\n }\n\n const width = recorded.end - recorded.start + 1;\n const claimedSpans = [...claimed].map((d) => d.span);\n // No budget: a truncated search would call an intact range changed, and\n // the band-first order keeps the common small shift fast.\n const windows = findWindows(page.body, width, entry.integrity, undefined, { around: recorded.start, budget: Infinity })\n .starts.map((start) => ({ span: { start, end: start + width - 1 } }))\n .filter((w) => !claimedSpans.some((s) => sameSpan(s, w.span)));\n const found = nearest(windows, recorded);\n if (found === undefined) {\n results.push({ status: \"changed\", entry, span: recorded });\n continue;\n }\n const { contradiction, anyMachine } = scanEvidence(evidenceByLine, found.span, machine);\n if (contradiction !== undefined) {\n results.push({ status: \"stale\", entry, span: found.span, evidence: contradiction });\n continue;\n }\n const blank = blankEdges(page.body, found.span);\n if (blank !== undefined) {\n results.push({ status: \"stale\", entry, span: found.span, blank });\n continue;\n }\n results.push({\n status: sameSpan(found.span, recorded) ? \"current\" : \"moved\",\n entry,\n span: found.span,\n ...(anyMachine ? {} : { noEvidence: true as const }),\n });\n }\n\n const covering = results.map((r) => r.span);\n for (const d of derived) {\n if (claimed.has(d)) continue;\n let uncovered = false;\n for (let n = d.span.start; n <= d.span.end && !uncovered; n++) {\n if (isBlankLine(page.body[n - 1])) continue;\n uncovered = !covering.some((s) => n >= s.start && n <= s.end);\n }\n if (uncovered) results.push({ status: \"unset\", entry: d.entry, span: d.span, evidence: d.evidence });\n }\n return results;\n}\n\n/**\n * The `provenance` value `derive` writes. Current entries stay as they are,\n * moved entries stay with `lines` rewritten, and every derived range not\n * already kept is added, which re-derives changed and stale entries and adds\n * unset ones. A changed entry no machine now answers for is dropped (stress\n * test 11: the bytes are gone); an entry nothing contradicts never is. An\n * entry stale for its blank lines is kept trimmed to its first and last\n * non-blank line and pinned over those, or dropped when it holds only blank\n * lines (proposal 0071). A derived range not already kept is the newer\n * account of its lines, of any machine: a kept entry within it is dropped,\n * and one it partly overlaps keeps only the lines outside it, split in two\n * when the range sits in its middle. Each piece is trimmed of blank edges and\n * pinned over its own lines, or dropped when only blank lines are left. A\n * kept entry keeps any key outside the closed set. Ordered by start line,\n * stably.\n */\nexport function planProvenanceWrite(\n comparisons: readonly ProvenanceComparison[],\n derivation: ProvenanceDerivation,\n): ProvenanceEntry[] {\n const { body } = derivation.page;\n const same = (a: ProvenanceEntry, b: ProvenanceEntry): boolean =>\n a[\"generated-by\"] === b[\"generated-by\"] && String(a.lines) === String(b.lines) && a.integrity === b.integrity;\n const kept: Written[] = [];\n // An entry identical to one already kept is written once: a blank-edged\n // entry trimmed can land on the lines of another entry the stamp holds.\n const keep = (entry: ProvenanceEntry, span: PageLines): void => {\n if (!kept.some((k) => same(k.entry, entry))) kept.push({ entry, span });\n };\n for (const r of comparisons) {\n if (r.status === \"current\") keep(r.entry, r.span);\n else if (r.status === \"moved\") keep({ ...r.entry, lines: lineSpec(r.span) }, r.span);\n else if (r.status === \"stale\" && r.blank !== undefined) {\n const span = trimBlank(body, r.span);\n if (span !== undefined) keep({ ...r.entry, lines: lineSpec(span), integrity: pinOf(body, span) }, span);\n }\n }\n /**\n * What is left of a kept entry beside a derived range: the pieces outside\n * it, each trimmed of blank edges, pinned over its own lines, and dropped\n * when only blank lines are left.\n */\n const outside = (k: Written, d: PageLines): Written[] => {\n if (k.span.end < d.start || k.span.start > d.end) return [k];\n const pieces: PageLines[] = [];\n if (k.span.start < d.start) pieces.push({ start: k.span.start, end: d.start - 1 });\n if (k.span.end > d.end) pieces.push({ start: d.end + 1, end: k.span.end });\n return pieces.flatMap((piece) => {\n const span = trimBlank(body, piece);\n if (span === undefined) return [];\n return [{ entry: { ...k.entry, lines: lineSpec(span), integrity: pinOf(body, span) }, span }];\n });\n };\n let out: Written[] = [...kept];\n const derived = new Set<Written>();\n for (const d of derivation.derived) {\n if (kept.some((k) => same(k.entry, d.entry))) continue;\n out = out.flatMap((k) => (derived.has(k) ? [k] : outside(k, d.span)));\n const written = { entry: d.entry, span: d.span };\n derived.add(written);\n out.push(written);\n }\n const unique: Written[] = [];\n for (const k of out) if (!unique.some((u) => same(u.entry, k.entry))) unique.push(k);\n return unique.sort((a, b) => a.span.start - b.span.start).map((k) => k.entry);\n}\n\n/** An entry a write plans, with the body lines it covers. */\ninterface Written {\n entry: ProvenanceEntry;\n span: PageLines;\n}\n\n// ---------------------------------------------------------------------------\n// Output: the JSON ranges, findings, and get's value\n// ---------------------------------------------------------------------------\n\n/** One range of `DerivedField.ranges`, in file lines. */\nexport interface RangeResult {\n lines: string;\n \"generated-by\": string;\n integrity: string;\n status: ProvenanceStatus;\n /** `uncommitted`, `blame <sha7>`, or `pin` when only the pin speaks for the range. */\n evidence: string;\n /** What the record said before: on `moved` and `stale` only. */\n from?: { lines: string; \"generated-by\": string };\n /** Whether `derive` wrote this range; always false until it does. */\n written: boolean;\n}\n\nconst short = (sha: string): string => sha.slice(0, 7);\n\n/** File lines as a report spells them. */\nfunction fileSpelling(span: PageLines, bodyLine: number): string {\n return spellLines(toFileLines(span, bodyLine));\n}\n\nfunction evidenceText(evidence: LineEvidence | undefined): string {\n if (evidence?.machine === undefined) return \"pin\";\n return evidence.rule === 1 ? \"uncommitted\" : `blame ${short(evidence.sha)}`;\n}\n\n/** Where a finding says the evidence came from: the short sha, or `uncommitted`. */\nfunction evidenceRef(evidence: LineEvidence | undefined): string {\n if (evidence === undefined) return \"no evidence\";\n return evidence.rule === 1 ? \"uncommitted\" : short(evidence.sha);\n}\n\n/** The comparisons as `DerivedField.ranges` reports them. `bodyLine` is the page's. */\nexport function rangeResults(comparisons: readonly ProvenanceComparison[], bodyLine: number): RangeResult[] {\n return comparisons.map((r) => {\n const lines = fileSpelling(r.span, bodyLine);\n const recorded = parseLines(r.entry.lines);\n const from = recorded === undefined ? undefined : fileSpelling(recorded, bodyLine);\n const machine = r.entry[\"generated-by\"];\n switch (r.status) {\n case \"stale\":\n return {\n lines,\n \"generated-by\": r.evidence?.machine ?? machine,\n integrity: r.entry.integrity,\n status: r.status,\n evidence: evidenceText(r.evidence),\n ...(from !== undefined ? { from: { lines: from, \"generated-by\": machine } } : {}),\n written: false,\n };\n case \"moved\":\n return {\n lines,\n \"generated-by\": machine,\n integrity: r.entry.integrity,\n status: r.status,\n evidence: \"pin\",\n ...(from !== undefined ? { from: { lines: from, \"generated-by\": machine } } : {}),\n written: false,\n };\n case \"unset\":\n return { lines, \"generated-by\": machine, integrity: r.entry.integrity, status: r.status, evidence: evidenceText(r.evidence), written: false };\n case \"current\":\n case \"changed\":\n return { lines, \"generated-by\": machine, integrity: r.entry.integrity, status: r.status, evidence: \"pin\", written: false };\n }\n });\n}\n\n/** How a finding says an entry's blank lines make it malformed. */\nconst BLANK_WORDS: Record<BlankEdges, string> = {\n only: \"hold only blank lines\",\n start: \"start on a blank line\",\n end: \"end on a blank line\",\n both: \"start and end on blank lines\",\n};\n\n/**\n * The findings `validate` and `derive --check` file for a page's provenance:\n * one per changed, stale or unset range, in 0046's words. `line` is the\n * range's file line on the page, and `subject` carries the pin (the recorded\n * one for changed and stale, the derived one for unset), so a baseline that\n * forgives one range does not forgive the rest.\n */\nexport function provenanceFindings(comparisons: readonly ProvenanceComparison[], bodyLine: number): FieldError[] {\n const findings: FieldError[] = [];\n for (const r of comparisons) {\n const machine = r.entry[\"generated-by\"];\n const lines = fileSpelling(r.span, bodyLine);\n let message: string;\n switch (r.status) {\n case \"changed\":\n message = `provenance lines ${lines} changed since ${machine} wrote them`;\n break;\n case \"stale\":\n message =\n r.blank !== undefined\n ? `provenance lines ${lines} say ${machine} but ${BLANK_WORDS[r.blank]}`\n : `provenance lines ${lines} say ${machine}; blame says ${r.evidence?.machine ?? \"another machine\"} (${evidenceRef(r.evidence)})`;\n break;\n case \"unset\":\n message = `provenance is unset for lines ${lines}; blame says ${machine} (${evidenceRef(r.evidence)})`;\n break;\n case \"current\":\n case \"moved\":\n continue;\n }\n findings.push({\n schema: DERIVED_STALE_SCHEMA,\n keyword: DERIVED_KEYWORD,\n subject: `provenance ${r.entry.integrity}`,\n instancePath: PROVENANCE_POINTER,\n message: `${message} — run manni meta derive`,\n line: toFileLines(r.span, bodyLine).start,\n });\n }\n return findings;\n}\n\n/** `get`'s value: `lines 12-31 claude-fable-5; lines 44 claude-sonnet-5`, in file lines. */\nexport function renderProvenanceValue(entries: readonly ProvenanceEntry[], bodyLine: number): string {\n return entries\n .map((e) => {\n const span = parseLines(e.lines);\n const lines = span === undefined ? String(e.lines) : fileSpelling(span, bodyLine);\n return `lines ${lines} ${e[\"generated-by\"]}`;\n })\n .join(\"; \");\n}\n\n// ---------------------------------------------------------------------------\n// Ranged attribution: `manni meta derive <path>:L1-L2 --generated-by <name>`\n// ---------------------------------------------------------------------------\n\n/**\n * Split `<path>:L` or `<path>:L1-L2` as `cite add` splits a page argument:\n * the last `:L` suffix, so a drive letter is not a range. A range that ends\n * before it starts is refused in 0046's words.\n */\nexport function parseProvenanceTarget(arg: string): { page: string; lines?: PageLines } {\n try {\n return splitPageArgument(arg);\n } catch (err) {\n if (err instanceof LineRangeError) throw new DocmetaError(`${arg} ends before it starts.`);\n throw err;\n }\n}\n\nexport interface AttributeRangeInput {\n /** The positional as typed, `<path>:L` or `<path>:L1-L2`, in file lines. */\n target: string;\n content: string;\n blame: readonly BlameLine[];\n commits: ReadonlyMap<string, CommitEvidence>;\n machines?: readonly string[];\n generatedBy: string;\n fenced?: boolean;\n /**\n * The page as `readProvenancePage` reads `content`, when the caller has it.\n * Several ranges on one file then share one read instead of one each.\n */\n page?: ProvenancePage;\n}\n\n/**\n * The entry a named range writes. Committed or not, its lines go to\n * `generatedBy`, unless rules 2 to 4 name a different machine for any of\n * them: the first such line in file order is named in the refusal. Evidence\n * that names the same machine, or none, lets the range through. Every\n * refusal is a `DocmetaError` (exit 2) in 0046's words.\n *\n * A blank line carries no authorship (proposal 0071): its evidence is never\n * a refusal, the entry is trimmed to the range's first and last non-blank\n * line, and a range of only blank lines writes nothing.\n */\nexport function attributeRange(input: AttributeRangeInput): ProvenanceEntry | undefined {\n const { target } = input;\n const { page: path, lines: range } = parseProvenanceTarget(target);\n if (range === undefined) throw new Error(`provenance: ${target} names no lines`);\n const page = input.page ?? readProvenancePage(input.content, readOptions(input.fenced));\n if (range.end > page.lines.length) {\n throw new DocmetaError(\n `${path} has no lines ${spellLines(range)}: the file ends at line ${page.lines.length}.`,\n );\n }\n if (range.start < page.bodyLine) {\n throw new DocmetaError(\n `${target} reaches into the frontmatter; provenance pins body lines, which start at line ${page.bodyLine}.`,\n );\n }\n const ctx = contextOf(input);\n for (const line of input.blame) {\n if (line.finalLine < range.start || line.finalLine > range.end) continue;\n if (isBlankLine(page.lines[line.finalLine - 1])) continue;\n const evidence = recordedEvidence(line, ctx);\n if (evidence.machine !== undefined && evidence.machine !== input.generatedBy) {\n throw new DocmetaError(\n `${target}: blame attributes these lines to ${evidence.machine} (${short(evidence.sha)}); --generated-by cannot overrule a recorded machine.`,\n );\n }\n }\n const span = trimBlank(page.body, toBodyLines(range, page.bodyLine));\n if (span === undefined) return undefined;\n return { \"generated-by\": input.generatedBy, lines: lineSpec(span), integrity: pinOf(page.body, span) };\n}\n","/**\n * The pin engine: refer to content by its lines and a hash of them, and find\n * those lines again when they move. cite pins a citation's two ends with it,\n * and meta pins the fields a document derives; neither owns it.\n *\n * The hashing rule, stated once (proposal 0044 § The vocabulary):\n * UTF-8; strip one leading BOM; CRLF → LF; split on LF; drop the empty element\n * a trailing LF leaves; take lines L1..L2 inclusive (1-based); join with LF; no\n * trailing LF; trailing whitespace kept. Plain: `sha256-` and sha256(text).\n * Keyed (an encrypted value): `hmac-sha256-` and the family's keyed pin,\n * HMAC-SHA256 under a key derived from the encryption key (proposal 0045).\n */\n// Straight to the module rather than meta's barrel: shared code sits under\n// every tool, and `integrity.ts` depends on nothing but node:crypto.\nimport { integrityOf } from \"../meta/core/integrity.js\";\nimport { KEYED_PIN_PREFIX, keyedPin } from \"./encryption.js\";\nimport { ToolError } from \"./errors.js\";\nimport { STDIN_LINES_MARKER } from \"./run.js\";\n\n/**\n * A line range that runs past the end of the text, or ends before it starts.\n * Each tool rethrows it as its own error where its callers match on that.\n */\nexport class LineRangeError extends ToolError {\n constructor(message: string) {\n super(message);\n this.name = \"LineRangeError\";\n }\n}\n\n/** Lines as an entry writes them: an integer for one line, `\"L1-L2\"` for several. */\nexport type LineSpec = number | string;\n\n/** Page lines as an editor numbers them, 1-based and inclusive. */\nexport interface PageLines {\n start: number;\n end: number;\n}\n\n/** A 1-based inclusive range, either end optional: no `start` is the whole text, no `end` one line. */\nexport interface LineRange {\n start?: number;\n end?: number;\n}\n\n/** BOM stripped, CRLF folded to LF. */\nexport function normalizeText(text: string): string {\n const body = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;\n return body.replace(/\\r\\n/g, \"\\n\");\n}\n\n/** The normalized lines, without the empty element a trailing LF leaves. */\nexport function splitLines(text: string): string[] {\n const parts = normalizeText(text).split(\"\\n\");\n if (parts.length > 0 && parts[parts.length - 1] === \"\") parts.pop();\n return parts;\n}\n\n/**\n * The lines of a range joined by LF. Throws `LineRangeError` when the range\n * runs past the end of the text (`<label> has N lines; line M is out of range.`).\n */\nexport function sliceLines(lines: readonly string[], range?: LineRange, label?: string): string {\n const start = range?.start;\n if (start === undefined) return lines.join(\"\\n\");\n const end = range?.end ?? start;\n if (end < start) {\n // Both bounds can be in range, so without this a reversed range sliced\n // nothing and hashed as the pin of an empty span.\n throw new LineRangeError(`${label ?? \"the source\"} range ${String(start)}-${String(end)} ends before it starts.`);\n }\n if (start > lines.length || end > lines.length) {\n const first = start > lines.length ? start : end;\n throw new LineRangeError(`${label ?? \"the source\"} has ${lines.length} lines; line ${first} is out of range.`);\n }\n return lines.slice(start - 1, end).join(\"\\n\");\n}\n\n/** The pin of a range of `text`: plain, or the keyed pin under `key` when one is given. */\nexport function hashRange(text: string, range?: LineRange, key?: string): string {\n return hashLines(sliceLines(splitLines(text), range), key);\n}\n\n/**\n * The pin of already-joined lines: `sha256-<hex>`, or with `key` the\n * `hmac-sha256-<hex>` keyed pin an encrypted value carries. A plain pin\n * passes `undefined`.\n */\nexport function hashLines(joined: string, key?: string): string {\n return key === undefined ? integrityOf(Buffer.from(joined, \"utf8\")) : keyedPin(joined, key);\n}\n\n/** Whether a pin is keyed (`hmac-sha256-`), the form an encrypted value carries. */\nexport function isKeyedPin(pin: string): boolean {\n return pin.startsWith(KEYED_PIN_PREFIX);\n}\n\n/** The plain pin of a range of lines; undefined when the range falls outside them or ends before it starts. */\nexport function pinOfLines(lines: readonly string[], range: PageLines): string | undefined {\n if (range.start < 1 || range.end > lines.length || range.end < range.start) return undefined;\n return hashLines(lines.slice(range.start - 1, range.end).join(\"\\n\"));\n}\n\n/** Half-width of the band around the original position the blind move search tries first. */\nexport const MOVE_WINDOW_LINES = 2000;\n/** Default hashing budget for the blind move search, in bytes. */\nexport const MOVE_BUDGET_BYTES = 64 * 1024 * 1024;\n/** The widest range an entry may name, at either end: a wider one is refused. */\nexport const MAX_RANGE_LINES = 5000;\n\n/**\n * Bytes left to spend on settling one pin. Every search that classifies the\n * same end shares one of these, so the cap is the cost of settling that pin\n * rather than the cost of each search in turn (proposal 0055 § the budget).\n */\nexport interface SearchBudget {\n left: number;\n}\n\nexport interface FindWindowsOptions {\n /** The 1-based start line the range was pinned at: the blind search begins around it. */\n around?: number;\n /** The pinned lines as they were, when known: enables the first-line filter. */\n original?: readonly string[];\n /** Hashing budget for the blind search, in bytes. Default `MOVE_BUDGET_BYTES`. */\n budget?: number;\n /** A budget shared with the other searches settling this pin. Wins over `budget`. */\n counter?: SearchBudget;\n}\n\n/**\n * Pure move search over normalized lines: the 1-based start lines where a\n * window of `length` lines hashes to `pin`. `original` (the pinned lines as\n * they were, when known) enables the first-line filter. `key` keys the hash\n * for a keyed pin and is `undefined` for a plain one.\n */\nexport function findWindows(\n lines: readonly string[],\n length: number,\n pin: string,\n key: string | undefined,\n opts?: FindWindowsOptions,\n): { starts: number[]; truncated: boolean } {\n const starts: number[] = [];\n const lastStart = lines.length - length + 1;\n if (length < 1 || lastStart < 1) return { starts, truncated: false };\n\n const joined = (start: number): string => lines.slice(start - 1, start - 1 + length).join(\"\\n\");\n\n const original = opts?.original;\n if (original !== undefined) {\n const first = original[0];\n for (let start = 1; start <= lastStart; start++) {\n if (lines[start - 1] !== first) continue;\n let same = true;\n for (let i = 1; i < length; i++) {\n if (lines[start - 1 + i] !== original[i]) {\n same = false;\n break;\n }\n }\n if (same && hashLines(joined(start), key) === pin) starts.push(start);\n }\n return { starts, truncated: false };\n }\n\n // Blind: the band around the original position first, then the rest, so the\n // common small shift is found before the budget is anywhere near spent.\n const counter = opts?.counter;\n const budget = counter?.left ?? opts?.budget ?? MOVE_BUDGET_BYTES;\n const around = opts?.around ?? 1;\n const bandStart = Math.max(1, around - MOVE_WINDOW_LINES);\n const bandEnd = Math.min(lastStart, around + MOVE_WINDOW_LINES);\n const order: number[] = [];\n for (let start = bandStart; start <= bandEnd; start++) order.push(start);\n for (let start = 1; start < bandStart; start++) order.push(start);\n for (let start = bandEnd + 1; start <= lastStart; start++) order.push(start);\n\n let spent = 0;\n for (const start of order) {\n const text = joined(start);\n const bytes = Buffer.byteLength(text, \"utf8\");\n if (spent + bytes > budget) {\n if (counter !== undefined) counter.left = budget - spent;\n return { starts, truncated: true };\n }\n spent += bytes;\n if (hashLines(text, key) === pin) starts.push(start);\n }\n if (counter !== undefined) counter.left = budget - spent;\n return { starts, truncated: false };\n}\n\n/**\n * `\"L1-L2\"`, the only string form an entry may write, and `\"L\"`, which no\n * entry writes but every report spells (`spellLines`), so a spelling reads\n * back as the lines it names.\n */\nconst RANGE_SPEC = /^([1-9][0-9]*)(?:-([1-9][0-9]*))?$/;\n\n/**\n * The lines a `LineSpec` names. Undefined for a value that is neither a\n * positive integer nor `\"L1-L2\"` with `L1 <= L2`.\n */\nexport function parseLines(spec: LineSpec): PageLines | undefined {\n if (typeof spec === \"number\") {\n return Number.isInteger(spec) && spec >= 1 ? { start: spec, end: spec } : undefined;\n }\n const m = RANGE_SPEC.exec(spec);\n const startText = m?.[1];\n if (startText === undefined) return undefined;\n const start = Number(startText);\n const endText = m?.[2];\n const end = endText === undefined ? start : Number(endText);\n return end < start ? undefined : { start, end };\n}\n\n/** Lines as an entry writes them: the integer for one line, `\"L1-L2\"` otherwise. */\nexport function lineSpec(lines: PageLines): LineSpec {\n return lines.start === lines.end ? lines.start : `${String(lines.start)}-${String(lines.end)}`;\n}\n\n/** Lines as a report spells them: `\"9\"` or `\"9-12\"`. */\nexport function spellLines(lines: PageLines): string {\n return String(lineSpec(lines));\n}\n\n/** Body lines as file lines: body line 1 is the file line `bodyLine`, the first after the frontmatter. */\nexport function toFileLines(lines: PageLines, bodyLine: number): PageLines {\n return { start: bodyLine + lines.start - 1, end: bodyLine + lines.end - 1 };\n}\n\n/** File lines as body lines. */\nexport function toBodyLines(lines: PageLines, bodyLine: number): PageLines {\n return { start: lines.start - bodyLine + 1, end: lines.end - bodyLine + 1 };\n}\n\n/**\n * Split `docs/limits.md:9` or `docs/limits.md:14-18` into the page and its\n * lines. Only a trailing `:L` or `:L1-L2` is read as lines, so a path that\n * carries a colon keeps it, and `-:9` still reads the page from stdin. Throws\n * `LineRangeError` for an end line before the start.\n */\nexport function splitPageArgument(arg: string): { page: string; lines?: PageLines } {\n // `-:9` reaches commander as an operand only after the bin rewrites its\n // leading `-` to the marker (`run.ts`); both spellings name stdin, `-`, and\n // the same lines.\n const text = arg.startsWith(STDIN_LINES_MARKER) ? `-${arg.slice(STDIN_LINES_MARKER.length)}` : arg;\n const m = /:([1-9][0-9]*)(?:-([1-9][0-9]*))?$/.exec(text);\n const head = m === null ? text : text.slice(0, m.index);\n if (m === null || head === \"\") return { page: arg };\n const start = Number(m[1]);\n const end = m[2] === undefined ? start : Number(m[2]);\n if (end < start) {\n throw new LineRangeError(`Invalid range \"${arg}\": end line ${end} is before start line ${start}.`);\n }\n return { page: head, lines: { start, end } };\n}\n","/**\n * The one adapter between `derive:` as the config file spells it and the\n * derive context as the sources want it.\n *\n * The config is a user-facing document, so it says `timeout: 30`, in whole\n * seconds. Every source downstream measures in milliseconds, because that is\n * what `child_process` takes. Exactly one place should know both, and this is\n * it. It lived in `table.ts` first, which made the SQL projection the owner\n * of a unit conversion four commands need and only one of them is about\n * tables.\n */\nimport type { DeriveConfig } from \"../config.js\";\nimport { DEFAULT_MACHINES } from \"./provenance.js\";\nimport type { DeriveCommand } from \"./types.js\";\n\n/** How long a configured command may run when its entry says nothing: 60 s. */\nexport const DEFAULT_COMMAND_TIMEOUT_MS = 60_000;\n\n/**\n * The `command` source's table as the derive context wants it, from the\n * config's spelling: `timeout` is in seconds there and `timeoutMs` here.\n * Undefined when the config configures no command, so a context built from\n * it consults the source for nothing.\n */\nexport function commandsOf(\n config?: DeriveConfig,\n): Readonly<Record<string, DeriveCommand>> | undefined {\n if (config?.commands === undefined) return undefined;\n const out: Record<string, DeriveCommand> = {};\n for (const [field, c] of Object.entries(config.commands)) {\n out[field] = {\n run: c.run,\n timeoutMs:\n c.timeout === undefined ? DEFAULT_COMMAND_TIMEOUT_MS : Math.round(c.timeout * 1000),\n };\n }\n return out;\n}\n\n/**\n * `derive.machines` as the sources read it (proposal 0046): the configured\n * globs, or `[\"*[bot]\"]` when the config sets none, which is exactly the\n * `[bot]` suffix rule `authors` followed before the key existed.\n */\nexport function machinesOf(config?: DeriveConfig): readonly string[] {\n return config?.machines ?? DEFAULT_MACHINES;\n}\n","/**\n * The derived channel's front door: one call resolves every requested field\n * for every input from the sources the run consults.\n *\n * Three rules live here and nowhere else:\n *\n * 1. **A source is consulted only when a requested field can come from it.**\n * `FIELD_SOURCES` says which for the built-ins, and `derive.commands`\n * which keys the `command` source answers; the run's `sources` list\n * narrows it. A source nobody asked for is never spawned and never\n * reported, and a command for a field the run did not request is never\n * spawned either.\n * 2. **The review sources ride on git, and the origin remote picks one.**\n * `github` and `gitlab` both read the merged change behind a document's\n * newest body-changing commit, which only the git walk can name, so\n * either without `git` is reported unavailable with the fix rather than\n * silently answering null. Per repository root, the origin remote says\n * which host the repository lives on, and only the review source of that\n * name is consulted and reported: a run that allows both on a GitHub\n * repository reports `github` alone. A run that allows only the other\n * one is told which host the origin is, and what to change.\n * 3. **Precedence is per field, first non-null wins.** `reviewed-by` and\n * `last-reviewed` prefer the host's approvals over a `Reviewed-by`\n * trailer; every other field has one source.\n *\n * Availability is reported, not thrown: a caller decides what an\n * unavailable source means for its run through `assertSourcesAvailable`,\n * because the hint differs per command (`--no-derive` on validate,\n * `--sources` on derive).\n */\nimport { dirname, resolve } from \"node:path\";\nimport { findGitRoot } from \"../../../shared/git-root.js\";\nimport { DocmetaError } from \"../../types.js\";\nimport { REVIEW_CACHE_DIR } from \"./cache.js\";\nimport { deriveFromCodeowners } from \"./codeowners.js\";\nimport { deriveFromCommands } from \"./command.js\";\nimport { createReviewClient, deriveFromReviews, type ReviewFacts } from \"./reviews.js\";\nimport { deriveFromGit, type GitFacts } from \"./git.js\";\nimport type { ProvenanceDerivation } from \"./provenance.js\";\nimport { isBuiltinField } from \"./types.js\";\nimport type {\n BuiltinDerivableField,\n DerivableField,\n DeriveCommand,\n DeriveContext,\n DerivedRecord,\n DerivedValue,\n DeriveInput,\n DeriveSource,\n RemoteIdentity,\n ReviewClient,\n SourceStatus,\n} from \"./types.js\";\n\n/** Which sources can state each built-in field, in precedence order. */\nexport const FIELD_SOURCES: Readonly<Record<BuiltinDerivableField, readonly DeriveSource[]>> = {\n created: [\"git\"],\n \"last-updated\": [\"git\"],\n authors: [\"git\"],\n owner: [\"codeowners\"],\n \"reviewed-by\": [\"github\", \"gitlab\", \"git\"],\n \"last-reviewed\": [\"github\", \"gitlab\", \"git\"],\n provenance: [\"git\"],\n};\n\n/** The sources that read a host's review record; one per host, named for it. */\ntype ReviewSource = RemoteIdentity[\"kind\"];\n\nconst REVIEW_SOURCES: readonly ReviewSource[] = [\"github\", \"gitlab\"];\n\n/** How the host is spelled to a person, as opposed to as a source name. */\nconst HOST_NAME: Readonly<Record<ReviewSource, string>> = {\n github: \"GitHub\",\n gitlab: \"GitLab\",\n};\n\nexport interface DeriveResult {\n /** Keyed by `DeriveInput.label`; every input has a record. */\n records: Map<string, DerivedRecord>;\n /**\n * One status per source the run consulted. A source nobody asked for is\n * absent, and so is whichever of `github` and `gitlab` the origin remote does\n * not point at. Absent means not applicable here, never unavailable.\n */\n sources: Partial<Record<DeriveSource, SourceStatus>>;\n /**\n * The provenance derivation per input label (proposal 0046), for the\n * comparison with a page's stamp: present only when `provenance` was\n * requested and the git source answered.\n */\n provenance?: ReadonlyMap<string, ProvenanceDerivation>;\n}\n\n/**\n * Which sources can state a field, in precedence order: the built-in table\n * for one of the six, `command` for a key of `commands`, nothing otherwise.\n * A built-in never reaches the command arm, whatever the table says.\n */\nexport function sourcesFor(\n field: DerivableField,\n commands?: Readonly<Record<string, DeriveCommand>>,\n): readonly DeriveSource[] {\n if (isBuiltinField(field)) return FIELD_SOURCES[field];\n if (commands !== undefined && Object.hasOwn(commands, field)) return [\"command\"];\n return [];\n}\n\n/** The sources a run consults: requested, and able to state a requested field. */\nexport function consultedSources(\n fields: readonly DerivableField[],\n sources: readonly DeriveSource[],\n commands?: Readonly<Record<string, DeriveCommand>>,\n): DeriveSource[] {\n const needed = new Set<DeriveSource>();\n for (const field of fields) {\n for (const s of sourcesFor(field, commands)) needed.add(s);\n }\n return sources.filter((s) => needed.has(s));\n}\n\n/**\n * Throw the exit-2 error for the first consulted source that could not\n * answer. `hint` is the command's own way out, appended after a semicolon.\n */\nexport function assertSourcesAvailable(\n sources: Partial<Record<DeriveSource, SourceStatus>>,\n hint?: string,\n): void {\n for (const name of Object.keys(sources) as DeriveSource[]) {\n const status = sources[name];\n if (status === undefined || status.available) continue;\n const reason = status.reason ?? \"it could not answer\";\n throw new DocmetaError(\n `${name} source unavailable: ${reason}${hint === undefined ? \"\" : `; ${hint}`}`,\n );\n }\n}\n\nexport async function deriveMetadata(\n inputs: readonly DeriveInput[],\n ctx: DeriveContext,\n): Promise<DeriveResult> {\n const consulted = new Set(consultedSources(ctx.fields, ctx.sources, ctx.commands));\n const sources: Partial<Record<DeriveSource, SourceStatus>> = {};\n\n // git: the walk every other source builds on.\n let git: Map<string, GitFacts> = new Map();\n if (consulted.has(\"git\")) {\n const result = await deriveFromGit(inputs, {\n cwd: ctx.cwd,\n now: ctx.now,\n fields: ctx.fields,\n ...(ctx.generatedBy !== undefined ? { generatedBy: ctx.generatedBy } : {}),\n ...(ctx.machines !== undefined ? { machines: ctx.machines } : {}),\n });\n sources.git = result.status;\n git = result.records;\n }\n const provenance = new Map<string, ProvenanceDerivation>();\n for (const [label, facts] of git) {\n if (facts.provenanceDerivation !== undefined) provenance.set(label, facts.provenanceDerivation);\n }\n\n // Repository root per input: git's answer where it gave one, the .git walk otherwise.\n const rootCache = new Map<string, string | null>();\n const rootOf = (absPath: string): string | null => {\n const dir = dirname(absPath);\n let root = rootCache.get(dir);\n if (root === undefined) {\n root = findGitRoot(dir);\n rootCache.set(dir, root);\n }\n return root;\n };\n const rootFor = (input: DeriveInput): string | null =>\n git.get(input.label)?.root ?? rootOf(input.absPath);\n\n // codeowners\n let owners: Map<string, DerivedValue | null> = new Map();\n if (consulted.has(\"codeowners\")) {\n const result = await deriveFromCodeowners(inputs, {\n explicit: ctx.codeowners,\n configDir: ctx.configDir,\n rootOf,\n });\n sources.codeowners = result.status;\n owners = result.records;\n }\n\n // github / gitlab: one client per repository root, or the injected seam\n // for all. Which of the two a root uses is the origin remote's call.\n const requested = REVIEW_SOURCES.filter((s) => consulted.has(s));\n let reviews: Map<string, ReviewFacts> = new Map();\n if (requested.length > 0) {\n if (!consulted.has(\"git\")) {\n for (const s of requested) {\n sources[s] = {\n available: false,\n reason: `the ${s} source needs the git source to find each document's commits; add git to sources`,\n };\n }\n } else if (sources.git?.available === false) {\n // Git already failed the run; every review lookup starts from a commit\n // git names, so spawning gh/glab now would be wasted calls before the\n // same exit 2.\n for (const s of requested) {\n sources[s] = {\n available: false,\n reason: `the git source could not answer, so the ${s} source cannot locate any commit`,\n };\n }\n } else {\n const result = await deriveReviewsByRoot(inputs, git, rootFor, ctx, requested);\n Object.assign(sources, result.status);\n reviews = result.records;\n }\n }\n\n // command: last, and only when nothing has failed yet. A configured\n // command is the one source that runs a program of the operator's own,\n // which may do more than report a value, so it is not spawned for a run\n // already destined for exit 2 — and the source that failed first is the\n // one whose reason `assertSourcesAvailable` reports.\n let commanded: Map<string, Record<string, DerivedValue | null>> = new Map();\n const doomed = Object.values(sources).some((s) => !s.available);\n if (consulted.has(\"command\") && ctx.commands !== undefined && !doomed) {\n // Only the entries for fields this run asked for, so a narrowed\n // `--fields` spawns nothing it does not need.\n const wanted = new Set(ctx.fields);\n const commands = Object.fromEntries(\n Object.entries(ctx.commands).filter(([field]) => wanted.has(field)),\n );\n if (Object.keys(commands).length > 0) {\n const result = await deriveFromCommands(inputs, commands, { cwd: ctx.configDir ?? ctx.cwd });\n sources.command = result.status;\n commanded = result.records;\n }\n }\n\n const records = new Map<string, DerivedRecord>();\n for (const input of inputs) {\n const fields: DerivedRecord[\"fields\"] = {};\n const g = git.get(input.label);\n const r = reviews.get(input.label);\n const c = commanded.get(input.label);\n for (const field of ctx.fields) {\n let value: DerivedValue | null = null;\n for (const source of sourcesFor(field, ctx.commands)) {\n if (!consulted.has(source)) continue;\n const candidate = valueFrom(source, field, g, r, owners.get(input.label), c);\n if (candidate !== null) {\n value = candidate;\n break;\n }\n }\n fields[field] = value;\n }\n records.set(input.label, { file: input.label, fields });\n }\n return { records, sources, ...(provenance.size > 0 ? { provenance } : {}) };\n}\n\nfunction valueFrom(\n source: DeriveSource,\n field: DerivableField,\n git: GitFacts | undefined,\n reviews: ReviewFacts | undefined,\n owner: DerivedValue | null | undefined,\n commanded: Readonly<Record<string, DerivedValue | null>> | undefined,\n): DerivedValue | null {\n switch (source) {\n case \"git\":\n if (git === undefined || !isBuiltinField(field) || field === \"owner\") return null;\n return git[field];\n case \"command\":\n return commanded?.[field] ?? null;\n case \"codeowners\":\n return field === \"owner\" ? (owner ?? null) : null;\n case \"github\":\n case \"gitlab\": {\n if (reviews === undefined) return null;\n if (field !== \"reviewed-by\" && field !== \"last-reviewed\") return null;\n // A fact answers for the source of the host it came from, and no other.\n const fact = reviews[field];\n return fact !== null && fact.source === source ? fact : null;\n }\n }\n}\n\n/**\n * Consult the review record for each repository root that holds an input.\n *\n * The root's origin remote picks the source: a GitHub origin uses `github`,\n * a GitLab origin `gitlab`, and only the one used is reported. When the\n * origin names a host whose source was not requested, that requested source\n * is reported unavailable with the host named and the fix spelled out. With\n * no origin at all, every requested review source is unavailable, because\n * nothing tells the two apart.\n */\nasync function deriveReviewsByRoot(\n inputs: readonly DeriveInput[],\n git: ReadonlyMap<string, GitFacts>,\n rootFor: (input: DeriveInput) => string | null,\n ctx: DeriveContext,\n requested: readonly ReviewSource[],\n): Promise<{ status: Partial<Record<ReviewSource, SourceStatus>>; records: Map<string, ReviewFacts> }> {\n const byRoot = new Map<string, DeriveInput[]>();\n for (const input of inputs) {\n const root = rootFor(input);\n if (root === null) continue;\n const bucket = byRoot.get(root) ?? [];\n bucket.push(input);\n byRoot.set(root, bucket);\n }\n const status: Partial<Record<ReviewSource, SourceStatus>> = {};\n const records = new Map<string, ReviewFacts>();\n const unavailable = (\n which: readonly ReviewSource[],\n reason: string,\n ): { status: Partial<Record<ReviewSource, SourceStatus>>; records: Map<string, ReviewFacts> } => {\n for (const s of which) status[s] = { available: false, reason };\n return { status, records: new Map() };\n };\n if (byRoot.size === 0) {\n return unavailable(requested, \"no git repository contains the documents\");\n }\n const cacheDir = resolve(ctx.configDir ?? ctx.cwd, REVIEW_CACHE_DIR);\n for (const [root, bucket] of byRoot) {\n const client: ReviewClient =\n ctx.reviews ??\n (await createReviewClient(root, { cwd: ctx.cwd, cache: ctx.cache, cacheDir, requested }));\n const identity = await client.detect();\n if (identity === null) {\n // No origin, or a host that names neither platform: the client's own\n // status says which, and names the fix.\n const s = await client.status();\n return unavailable(requested, s.reason ?? \"no origin remote to tell GitHub from GitLab\");\n }\n const source = identity.kind;\n if (!requested.includes(source)) {\n return unavailable(\n requested,\n `the origin remote is ${identity.host}, which is ${HOST_NAME[source]}; add ${source} to sources, or drop reviewed-by and last-reviewed from the managed fields`,\n );\n }\n const result = await deriveFromReviews(\n bucket.map((input) => ({\n label: input.label,\n sha: git.get(input.label)?.lastBodyCommit ?? null,\n })),\n client,\n );\n // One root that cannot answer makes the source unavailable for the run:\n // a half-derived review field would read as \"nobody approved\", which is\n // the false green the whole channel refuses.\n if (!result.status.available) {\n status[source] = result.status;\n return { status, records: new Map() };\n }\n status[source] = result.status;\n for (const [label, facts] of result.records) records.set(label, facts);\n }\n return { status, records };\n}\n\n","/**\n * The GitHub or GitLab review cache: cross-run, for merged-change answers.\n *\n * A merged pull request is history: its approvals cannot change, so the\n * answer for `host/project/sha` is good forever and there is no TTL. An\n * *open* PR's answer is the opposite — the next approval changes it — so a\n * `null` from the host is never written. `--no-cache` disables both\n * directions for one run.\n *\n * Same shape as `schema-cache.ts`: one file per key under\n * `.manni/meta/review-cache/`, named by a digest so the key (which carries\n * `/`) can never decide where a write lands; a malformed entry is a miss;\n * a failed write is swallowed, because a read-only checkout must cost the\n * next run one `gh` call, not this run its result. Synchronous, because a\n * `set()` the caller does not await must still be on disk when the next\n * process starts.\n */\nimport { createHash } from \"node:crypto\";\nimport { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ReviewClient, RemoteIdentity, MergedChange } from \"./types.js\";\n\n/** Where the GitHub or GitLab review cache lives, relative to the project root. `.manni/` is gitignored. */\nexport const REVIEW_CACHE_DIR = \".manni/meta/review-cache\";\n\n/** The only entry format this version understands. */\nexport const REVIEW_CACHE_VERSION = 1;\n\ninterface Entry {\n version: number;\n /** `host/project/sha`; re-checked on read. */\n key: string;\n change: MergedChange;\n}\n\n/** The GitHub or GitLab review cache: one immutable merged change per `host/project/sha`. */\nexport class ReviewCache {\n constructor(\n private readonly dir: string,\n private readonly enabled: boolean,\n ) {}\n\n entryPath(key: string): string {\n const digest = createHash(\"sha256\").update(key).digest(\"hex\");\n return join(this.dir, `${digest}.json`);\n }\n\n /** The cached change, or `undefined` for a miss. Never `null`: nulls are not stored. */\n get(key: string): MergedChange | undefined {\n if (!this.enabled) return undefined;\n let raw: unknown;\n try {\n raw = JSON.parse(readFileSync(this.entryPath(key), \"utf8\"));\n } catch {\n return undefined;\n }\n if (!isRecord(raw)) return undefined;\n if (raw.version !== REVIEW_CACHE_VERSION || raw.key !== key) return undefined;\n const change = readChange(raw.change);\n return change ?? undefined;\n }\n\n set(key: string, value: MergedChange): void {\n if (!this.enabled) return;\n const entry: Entry = { version: REVIEW_CACHE_VERSION, key, change: value };\n const path = this.entryPath(key);\n // Temp file beside the target plus rename, so a reader never sees half an\n // entry. Synchronous: see the module comment.\n const tmp = `${path}.${process.pid}-${Math.random().toString(36).slice(2, 8)}.tmp`;\n try {\n mkdirSync(this.dir, { recursive: true });\n writeFileSync(tmp, `${JSON.stringify(entry, null, 2)}\\n`, \"utf8\");\n renameSync(tmp, path);\n } catch {\n // Intentionally silent: see the module comment.\n try {\n rmSync(tmp, { force: true });\n } catch {\n // The temp file was never created, or cannot be removed either.\n }\n }\n }\n}\n\n/**\n * `client` with `mergedChangeFor` read through the cache. Only a merged\n * answer is stored. With no identity there is no key, and every call goes\n * straight through — which, for a client with no origin, is a `null`.\n */\nexport function cachedClient(\n client: ReviewClient,\n cache: ReviewCache,\n identity: RemoteIdentity | null,\n): ReviewClient {\n return {\n detect: () => client.detect(),\n status: () => client.status(),\n async mergedChangeFor(sha) {\n if (identity === null) return client.mergedChangeFor(sha);\n const key = `${identity.host}/${identity.project}/${sha}`;\n const hit = cache.get(key);\n if (hit !== undefined) return hit;\n const change = await client.mergedChangeFor(sha);\n if (change !== null) cache.set(key, change);\n return change;\n },\n };\n}\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** A stored change, or `null` when the file does not hold one. */\nfunction readChange(v: unknown): MergedChange | null {\n if (!isRecord(v)) return null;\n const { id, mergedAt, approvals } = v;\n if (typeof id !== \"number\" || typeof mergedAt !== \"string\") return null;\n if (!Array.isArray(approvals)) return null;\n const read: MergedChange[\"approvals\"] = [];\n for (const a of approvals as unknown[]) {\n if (!isRecord(a)) return null;\n if (typeof a.login !== \"string\" || typeof a.submittedAt !== \"string\") return null;\n read.push({ login: a.login, submittedAt: a.submittedAt });\n }\n return { id, mergedAt, approvals: read };\n}\n","/**\n * Derive `owner` from a CODEOWNERS file.\n *\n * Unlike `.gitignore` (see `../gitignore.ts`), CODEOWNERS is matched here\n * rather than by asking a tool. There is no `git check-codeowners`, and the\n * language is the small end of gitignore: GitHub allows no `!` negation and no\n * character ranges, there is one file rather than a stack of nested ones, and\n * the precedence rule is \"last match wins\". That is expressible with\n * picomatch once each pattern is rewritten the way git reads it — a pattern\n * with no slash matches at any depth, a leading `/` anchors it, a trailing\n * `/` names a directory, and any match on a directory covers what is under it.\n *\n * GitLab adds sections. Every section applies, so the owners of a file are the\n * union of the last match in each section; a section may carry default owners\n * for rules that list none, `^[Name]` marks approval optional (the owners are\n * still owners), and `[Name][n]` sets the approvals required. GitHub has no\n * sections, which is the same thing as one unnamed section.\n */\nimport { existsSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { dirname, relative, resolve, sep } from \"node:path\";\nimport picomatch from \"picomatch\";\nimport { errorMessage } from \"../../../shared/errors.js\";\nimport type { DerivedValue, SourceStatus } from \"./types.js\";\n\n/** Where a CODEOWNERS file may live, in the order GitHub and GitLab look. */\nexport const CODEOWNERS_LOCATIONS = [\n \".github/CODEOWNERS\",\n \"CODEOWNERS\",\n \"docs/CODEOWNERS\",\n \".gitlab/CODEOWNERS\",\n] as const;\n\nexport interface CodeownersRule {\n pattern: string;\n owners: string[];\n line: number;\n /** The GitLab section the rule sits in; absent in the unnamed default section. */\n section?: string;\n}\n\nexport interface CodeownersSection {\n name: string;\n optional: boolean;\n approvals?: number;\n defaultOwners: string[];\n}\n\nexport interface CodeownersFile {\n path: string;\n /** As the run reports it: forward slashes, relative to the base. */\n label: string;\n rules: CodeownersRule[];\n sections: CodeownersSection[];\n}\n\n/**\n * The first existing location in `CODEOWNERS_LOCATIONS` under `root`, or the\n * explicit path resolved against `root`; null if none exists. An explicit\n * path that is missing is null rather than a fallback to the search, because\n * a config that names a file means that file.\n */\nexport function findCodeowners(root: string, explicit?: string): string | null {\n if (explicit !== undefined) {\n const path = resolve(root, explicit);\n return existsSync(path) ? path : null;\n }\n for (const loc of CODEOWNERS_LOCATIONS) {\n const path = resolve(root, ...loc.split(\"/\"));\n if (existsSync(path)) return path;\n }\n return null;\n}\n\n/** `[Name]`, `^[Name]`, `[Name][2]`, each optionally followed by default owners. */\nconst SECTION_HEADER = /^(\\^?)\\[([^\\]]+)\\](?:\\[(\\d+)\\])?(.*)$/;\n\n/** Tokens split on unescaped whitespace; `\\ ` stays inside its token. */\nconst TOKEN = /(?:\\\\.|[^\\s\\\\])+/g;\n\n/**\n * Parse CODEOWNERS text. Never throws: a line that cannot be read as a rule\n * or a section header (an unclosed `[Name`, say) is skipped, since the host\n * would skip it too and a derived value should not fail the run over it.\n */\nexport function parseCodeowners(\n text: string,\n path: string,\n label: string,\n): CodeownersFile {\n const rules: CodeownersRule[] = [];\n const sections: CodeownersSection[] = [];\n let current: CodeownersSection | undefined;\n\n const lines = text.split(/\\r?\\n/);\n for (let i = 0; i < lines.length; i += 1) {\n const raw = lines[i] ?? \"\";\n const line = raw.trim();\n if (line === \"\" || line.startsWith(\"#\")) continue;\n\n if (line.startsWith(\"[\") || line.startsWith(\"^[\")) {\n const m = SECTION_HEADER.exec(line);\n if (!m) continue;\n const [, caret, rawName, approvals, rest] = m;\n const name = (rawName ?? \"\").trim();\n if (name === \"\") continue;\n const owners = tokens(rest ?? \"\");\n // GitLab merges repeated headers of one section, case-insensitively.\n const existing = sections.find(\n (s) => s.name.toLowerCase() === name.toLowerCase(),\n );\n if (existing) {\n if (owners.length > 0) existing.defaultOwners = owners;\n current = existing;\n continue;\n }\n const section: CodeownersSection = {\n name,\n optional: caret === \"^\",\n ...(approvals !== undefined ? { approvals: Number(approvals) } : {}),\n defaultOwners: owners,\n };\n sections.push(section);\n current = section;\n continue;\n }\n\n const [first, ...owners] = tokens(line);\n if (first === undefined) continue;\n const pattern = unescapePattern(first);\n if (pattern === \"\" || pattern === \"/\") continue;\n rules.push({\n pattern,\n owners,\n line: i + 1,\n ...(current ? { section: current.name } : {}),\n });\n }\n return { path, label, rules, sections };\n}\n\nfunction tokens(s: string): string[] {\n return s.match(TOKEN) ?? [];\n}\n\n/**\n * `\\ ` is a literal space and `\\#` a literal hash at the start; every other\n * escape is left for picomatch, where `\\*` still means a literal star.\n */\nfunction unescapePattern(token: string): string {\n return token.replace(/\\\\ /g, \" \").replace(/^\\\\#/, \"#\");\n}\n\n/**\n * Owners of `relPath` (repository-relative, forward slashes) under `file`,\n * with the line of the last winning rule; null when no rule in any section\n * matches. Within a section the last matching rule wins outright, a winner\n * that lists no owners takes the section's default owners, and a winner with\n * neither means \"no owner\" — a match that clears the field rather than a\n * miss. Across sections the winners' owners are unioned in section order,\n * first appearance kept.\n */\nexport function ownersFor(\n file: CodeownersFile,\n relPath: string,\n): { owners: string[]; line: number } | null {\n const matchers = matchersFor(file);\n const defaults = new Map(file.sections.map((s) => [s.name, s.defaultOwners]));\n\n // Section order is first appearance; the unnamed default section is first.\n const order: (string | undefined)[] = [undefined, ...file.sections.map((s) => s.name)];\n const winners = new Map<string | undefined, CodeownersRule>();\n file.rules.forEach((rule, i) => {\n if (matchers[i]?.(relPath)) winners.set(rule.section, rule);\n });\n if (winners.size === 0) return null;\n\n // The evidence line is the last winner that named an owner, so it points\n // at a rule the reader can see owners on. A winner that names nobody (no\n // owners, no section default) sets the line only when no winner named\n // anyone, which is the \"no owner\" clearing case.\n const owners: string[] = [];\n let line = 0;\n let lineFromOwner = false;\n for (const section of order) {\n const rule = winners.get(section);\n if (!rule) continue;\n const chosen =\n rule.owners.length > 0\n ? rule.owners\n : (section === undefined ? undefined : defaults.get(section)) ?? [];\n if (chosen.length > 0) {\n line = rule.line;\n lineFromOwner = true;\n } else if (!lineFromOwner) {\n line = rule.line;\n }\n for (const o of chosen) if (!owners.includes(o)) owners.push(o);\n }\n return { owners, line };\n}\n\nconst matcherCache = new WeakMap<CodeownersFile, ((p: string) => boolean)[]>();\n\nfunction matchersFor(file: CodeownersFile): ((p: string) => boolean)[] {\n let matchers = matcherCache.get(file);\n if (!matchers) {\n matchers = file.rules.map((r) => picomatch(toGlobs(r.pattern), PICOMATCH));\n matcherCache.set(file, matchers);\n }\n return matchers;\n}\n\n/**\n * `dot` because CODEOWNERS covers `.github/` and friends as a matter of\n * course, and gitignore's `*` never skips dotfiles. `windows: false` pins\n * posix semantics on every platform: the paths handed in are already\n * forward-slashed, and letting picomatch treat `\\` as a separator on Windows\n * would silently change what a `\\*` escape in the file means there.\n */\nconst PICOMATCH = { dot: true, windows: false } as const;\n\n/**\n * Rewrite one CODEOWNERS pattern into the picomatch globs that read it the\n * way git does. A pattern with no slash (or only a trailing one) matches at\n * any depth, so it gets a globstar-and-slash prefix; a leading `/` or a slash\n * in the middle anchors it to the root. A match on a directory covers\n * everything under it, so a second glob with a slash-and-globstar suffix is\n * included when the last segment is a literal name that could be one; a\n * trailing `/` means *only* a directory, so the bare pattern is then left\n * out. A last segment with a wildcard gets no twin: GitHub reads `docs/*`\n * as the files directly in `docs/`, not `docs/build-app/troubleshooting.md`,\n * and `*.md` already reaches any depth through its globstar prefix.\n */\nfunction toGlobs(pattern: string): string[] {\n let p = pattern;\n const dirOnly = p.endsWith(\"/\");\n if (dirOnly) p = p.slice(0, -1);\n let anchored = false;\n if (p.startsWith(\"/\")) {\n anchored = true;\n p = p.slice(1);\n } else if (p.includes(\"/\") && !p.startsWith(\"**/\")) {\n anchored = true;\n }\n const base = anchored || p.startsWith(\"**/\") ? p : `**/${p}`;\n if (dirOnly) return [`${base}/**`];\n const last = p.slice(p.lastIndexOf(\"/\") + 1);\n return /[*?[]/.test(last) ? [base] : [base, `${base}/**`];\n}\n\nexport interface CodeownersSourceOptions {\n /** Explicit path from config `derive.codeowners`, resolved against `configDir`. */\n explicit?: string;\n configDir?: string;\n /** Repository root for an input's absolute path; null when outside a repository. */\n rootOf: (absPath: string) => string | null;\n}\n\nexport interface CodeownersSourceResult {\n status: SourceStatus;\n /** Keyed by label; an input outside any repository is absent. */\n records: Map<string, DerivedValue | null>;\n}\n\nconst NOT_FOUND_REASON = `no CODEOWNERS file found (looked for ${CODEOWNERS_LOCATIONS.join(\", \")})`;\n\n/**\n * Derive owners for every input that sits in a repository. Inputs are grouped\n * by root and each root resolves its own file — the explicit path when the\n * config names one, otherwise the first location found under that root.\n *\n * A root with no file yields null records, and so does a run where no root\n * has one: a repository that declares no owners is a fact, not a broken\n * source, so the status stays available and carries the search as a\n * `reason` for the caller to surface as a notice. Only an explicit\n * `derive.codeowners` path that does not exist is unavailable — a configured\n * file that is missing is the operator's error, and silently answering null\n * there would be the green gate over nothing that the channel refuses.\n */\nexport async function deriveFromCodeowners(\n inputs: readonly { label: string; absPath: string }[],\n opts: CodeownersSourceOptions,\n): Promise<CodeownersSourceResult> {\n const records = new Map<string, DerivedValue | null>();\n\n const explicitPath =\n opts.explicit === undefined\n ? undefined\n : resolve(opts.configDir ?? process.cwd(), opts.explicit);\n if (explicitPath !== undefined && !existsSync(explicitPath)) {\n return {\n status: { available: false, reason: `CODEOWNERS not found at ${explicitPath}` },\n records,\n };\n }\n\n const byRoot = new Map<string, { label: string; absPath: string }[]>();\n const rootCache = new Map<string, string | null>();\n for (const input of inputs) {\n // Keyed by directory: every file in one directory shares its repository.\n const dir = dirname(input.absPath);\n let root = rootCache.get(dir);\n if (root === undefined) {\n root = opts.rootOf(input.absPath);\n rootCache.set(dir, root);\n }\n if (root === null) continue;\n const bucket = byRoot.get(root);\n if (bucket) bucket.push(input);\n else byRoot.set(root, [input]);\n }\n\n let found = 0;\n const parsed = new Map<string, Promise<CodeownersFile>>();\n for (const [root, bucket] of byRoot) {\n const path = explicitPath ?? findCodeowners(root);\n if (path === null) {\n for (const input of bucket) records.set(input.label, null);\n continue;\n }\n found += 1;\n const label = toPosix(relative(opts.configDir ?? root, path));\n const key = `${path}\\0${label}`;\n let file = parsed.get(key);\n if (!file) {\n file = readFile(path, \"utf8\").then((text) =>\n parseCodeowners(text, path, label),\n );\n parsed.set(key, file);\n }\n let owners: CodeownersFile;\n try {\n owners = await file;\n } catch (err) {\n // It was there a moment ago: deleted since, or not a readable file at\n // all. A source that cannot answer says so. It never crashes the run,\n // and it never answers \"nobody owns this\".\n return {\n status: {\n available: false,\n reason: `CODEOWNERS at ${label} could not be read: ${errorMessage(err)}`,\n },\n records,\n };\n }\n for (const input of bucket) {\n const rel = toPosix(relative(root, input.absPath));\n const hit = ownersFor(owners, rel);\n records.set(\n input.label,\n hit === null\n ? null\n : {\n value: hit.owners,\n source: \"codeowners\",\n evidence: `${label}:${hit.line}`,\n },\n );\n }\n }\n\n if (byRoot.size === 0) {\n return {\n status: { available: false, reason: \"no git repository contains the documents\" },\n records,\n };\n }\n if (found === 0 && explicitPath === undefined) {\n return { status: { available: true, reason: NOT_FOUND_REASON }, records };\n }\n return { status: { available: true }, records };\n}\n\nfunction toPosix(p: string): string {\n return p.split(sep).join(\"/\");\n}\n","/**\n * One child process, run to completion: stdout collected, stderr drained and\n * kept for the message, a timer that kills it. The review sources reach `gh`\n * and `glab` through this, and the `command` source reaches whatever the\n * config names; neither holds a token or opens a socket of its own.\n */\nimport { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\n\n/** How a client reaches the binary; tests point `bin` at node and a fake script. */\nexport interface SpawnOptions {\n /** Defaults to `gh` / `glab`, resolved on PATH. */\n bin?: string;\n /** Arguments placed before the command's own, such as a script for `node`. */\n prefixArgs?: string[];\n cwd: string;\n /** Kill the child after this long. Default 30 s. */\n timeoutMs?: number;\n}\n\nexport const DEFAULT_TIMEOUT_MS = 30_000;\n\n/**\n * How much of a child's output is kept, per stream. `gh` and `glab` answer\n * in JSON a page at a time, and a configured command reports one field's\n * value, so a stream past this is a program doing something else — `cat` on\n * the wrong file — and reading it to the end would trade the run's memory\n * for output nobody wants. The git walk caps itself the same way.\n */\nexport const MAX_OUTPUT_BYTES = 8 * 1024 * 1024;\n\nexport interface Run {\n /** Exit code; `null` when a signal ended the child. */\n code: number | null;\n stdout: string;\n stderr: string;\n timedOut: boolean;\n /** A stream passed `MAX_OUTPUT_BYTES` and the child was killed. */\n tooLarge: boolean;\n}\n\n/** The binary could not be started at all: nothing on PATH by that name. */\nexport class BinMissing extends Error {}\n\n/** One child, stdout collected, stderr drained and kept for the message. */\nexport function run(bin: string, args: string[], opts: SpawnOptions): Promise<Run> {\n return new Promise((settle, reject) => {\n let done = false;\n const finish = (r: Run): void => {\n if (done) return;\n done = true;\n settle(r);\n };\n const fail = (err: Error): void => {\n if (done) return;\n done = true;\n reject(err);\n };\n\n let child: ChildProcessWithoutNullStreams;\n try {\n child = spawn(bin, [...(opts.prefixArgs ?? []), ...args], {\n cwd: opts.cwd,\n windowsHide: true,\n });\n } catch (err) {\n fail(err instanceof Error ? err : new Error(String(err)));\n return;\n }\n\n let stdout = \"\";\n let stderr = \"\";\n let timedOut = false;\n let tooLarge = false;\n\n /**\n * Stop the child for good. `kill()` is SIGTERM, which a program may\n * trap, and `close` waits for the stdio streams as well as the exit —\n * a grandchild holding stdout keeps it pending. So the promise settles\n * here rather than waiting, and SIGKILL follows shortly after.\n *\n * `timer` is cleared here rather than left to `close`, for the same\n * reason: `close` is exactly the event this function refuses to wait\n * for. `clearTimeout` is idempotent, so the `close` handler may still\n * call it. The SIGKILL timer is deliberately not cleared — it is the\n * escalation, and it has to fire.\n *\n * `timer` is declared below this closure, so every caller must reach\n * `stop` from an async handler, as all of them do. Calling it straight\n * from the spawn path would hit the temporal dead zone.\n */\n const stop = (r: Omit<Run, \"code\">): void => {\n clearTimeout(timer);\n child.kill();\n setTimeout(() => child.kill(\"SIGKILL\"), 1_000).unref();\n finish({ code: null, ...r });\n };\n\n child.stdout.setEncoding(\"utf8\");\n child.stdout.on(\"data\", (chunk: string) => {\n stdout += chunk;\n if (stdout.length > MAX_OUTPUT_BYTES) {\n tooLarge = true;\n stop({ stdout, stderr, timedOut, tooLarge });\n }\n });\n // Drained *and* kept: a chatty CLI must not stall the pipe, and its last\n // line is what names the failure to the user.\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk: string) => {\n stderr += chunk;\n if (stderr.length > MAX_OUTPUT_BYTES) {\n tooLarge = true;\n stop({ stdout, stderr, timedOut, tooLarge });\n }\n });\n child.stdin.end();\n\n const timer = setTimeout(() => {\n timedOut = true;\n stop({ stdout, stderr, timedOut, tooLarge });\n }, opts.timeoutMs ?? DEFAULT_TIMEOUT_MS);\n\n // No binary on PATH lands here rather than throwing from spawn().\n child.on(\"error\", (err: NodeJS.ErrnoException) => {\n clearTimeout(timer);\n fail(err.code === \"ENOENT\" ? new BinMissing(err.message) : err);\n });\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n finish({ code, stdout, stderr, timedOut, tooLarge });\n });\n });\n}\n\n/** `gh api --hostname h repos/…`: the command as the user would type it. */\nexport function commandLine(bin: string, args: readonly string[]): string {\n return [bin, ...args].join(\" \");\n}\n\nexport function lastLine(text: string): string {\n const lines = text.split(/\\r?\\n/).filter((l) => l.trim() !== \"\");\n return lines.at(-1) ?? \"\";\n}\n","/**\n * The `command` source: a field derived by running whatever `derive.commands`\n * names for it. The value is the program's stdout — JSON when it parses as\n * JSON, the trimmed text otherwise, `null` when there is none.\n *\n * A command is spawned once per run, and its value copied into every\n * document's record, unless its argv carries `{path}`, in which case it is\n * spawned once per document with the document's label in place. The argv is\n * never handed to a shell: what the config lists is what runs.\n *\n * The first failure ends the source for the whole run, with nothing further\n * spawned: a program that is not on PATH, a timeout, a non-zero exit. A\n * half-derived field would read as \"the command said nothing\" for the\n * documents it never reached, which is the false green the whole channel\n * refuses. Availability is reported, never thrown, as the other sources do.\n */\nimport {\n BinMissing,\n MAX_OUTPUT_BYTES,\n lastLine,\n run,\n type Run,\n type SpawnOptions,\n} from \"./spawn.js\";\nimport { errorMessage } from \"../../../shared/errors.js\";\nimport type { DerivedValue, DeriveCommand, DeriveInput, SourceStatus } from \"./types.js\";\n\n/** The argv token a per-file command carries where the document's label goes. */\nexport const PATH_PLACEHOLDER = \"{path}\";\n\nexport interface CommandSourceOptions {\n /** Where the commands run: the config directory, else the run cwd. */\n cwd: string;\n /** Test seam: `bin` and `prefixArgs` replace the configured program. */\n spawn?: Partial<SpawnOptions>;\n}\n\nexport interface CommandSourceResult {\n status: SourceStatus;\n /** By label; every input present when available, keyed by field within. */\n records: Map<string, Record<string, DerivedValue | null>>;\n}\n\n/** Whether any argv element carries `{path}`, so the command runs once per document. */\nexport function isPerFile(command: DeriveCommand): boolean {\n return command.run.some((arg) => arg.includes(PATH_PLACEHOLDER));\n}\n\n/** The argv with every `{path}` replaced by the label, forward slashes as the run spells it. */\nexport function argvFor(command: DeriveCommand, label: string): string[] {\n return command.run.map((arg) => arg.split(PATH_PLACEHOLDER).join(label));\n}\n\n/**\n * What a command's stdout means: nothing when blank, the parsed value when it\n * is *structured* JSON, the trimmed text otherwise. A date or a version string\n * stays a string; a list or an object arrives as one.\n *\n * Only `{`, `[` and `\"` open a parse, and that boundary is the whole point.\n * A bare scalar is text a person wrote, and reading it as JSON silently\n * rewrites it: `1.10` becomes the number `1.1`, so a command reporting\n * version 1.10 stamps 1.1 into the document. A field wants the characters\n * the command printed. The structured forms are the reason a parse exists at\n * all — `verified-against` takes an object, and a list of anchors is a list —\n * and neither of those can be confused with prose.\n */\nexport function valueOf(stdout: string): unknown {\n const text = stdout.trim();\n if (text === \"\") return null;\n if (!/^[{[\"]/.test(text)) return text;\n try {\n return JSON.parse(text) as unknown;\n } catch {\n return text;\n }\n}\n\nexport async function deriveFromCommands(\n inputs: readonly DeriveInput[],\n commands: Readonly<Record<string, DeriveCommand>>,\n opts: CommandSourceOptions,\n): Promise<CommandSourceResult> {\n const records = new Map<string, Record<string, DerivedValue | null>>();\n const fields = Object.keys(commands);\n if (fields.length === 0 || inputs.length === 0) {\n return { status: { available: true }, records };\n }\n for (const input of inputs) records.set(input.label, {});\n\n for (const field of fields) {\n const command = commands[field];\n if (command === undefined) continue;\n if (isPerFile(command)) {\n for (const [label, record] of records) {\n const outcome = await runOne(field, argvFor(command, label), command.timeoutMs, opts);\n if (\"reason\" in outcome) return unavailable(outcome.reason);\n record[field] = outcome.value;\n }\n } else {\n const outcome = await runOne(field, command.run, command.timeoutMs, opts);\n if (\"reason\" in outcome) return unavailable(outcome.reason);\n for (const record of records.values()) record[field] = outcome.value;\n }\n }\n return { status: { available: true }, records };\n}\n\nfunction unavailable(reason: string): CommandSourceResult {\n return { status: { available: false, reason }, records: new Map() };\n}\n\ntype Outcome = { value: DerivedValue | null } | { reason: string };\n\n/** One spawn, with every failure turned into the reason the status carries. */\nasync function runOne(\n field: string,\n argv: readonly string[],\n timeoutMs: number,\n opts: CommandSourceOptions,\n): Promise<Outcome> {\n const [program, ...args] = argv;\n const where = `(derive.commands.${field})`;\n if (program === undefined) {\n return { reason: `no program to run ${where}` };\n }\n const line = argv.join(\" \");\n let result: Run;\n try {\n result = await run(opts.spawn?.bin ?? program, args, {\n ...opts.spawn,\n cwd: opts.spawn?.cwd ?? opts.cwd,\n timeoutMs,\n });\n } catch (err) {\n if (err instanceof BinMissing) {\n return { reason: `\\`${program}\\` is not on PATH ${where}` };\n }\n return { reason: `\\`${line}\\` could not be run: ${errorMessage(err)} ${where}` };\n }\n if (result.timedOut) {\n return { reason: `\\`${line}\\` timed out after ${String(timeoutMs / 1000)}s ${where}` };\n }\n if (result.tooLarge) {\n return {\n reason: `\\`${line}\\` wrote more than ${String(MAX_OUTPUT_BYTES / (1024 * 1024))} MiB; a command reports one field's value ${where}`,\n };\n }\n if (result.code !== 0) {\n const last = lastLine(result.stderr);\n const detail = last === \"\" ? \"no output on stderr\" : last;\n const exit = result.code === null ? \"killed by a signal\" : `exit ${String(result.code)}`;\n return { reason: `\\`${line}\\` failed (${exit}): ${detail} ${where}` };\n }\n const value = valueOf(result.stdout);\n return { value: value === null ? null : { value, source: \"command\", evidence: line } };\n}\n","/**\n * The review sources, `github` and `gitlab`: `reviewed-by` and `last-reviewed` from the pull request\n * or merge request that merged a document's newest body-changing commit.\n *\n * Reached through `gh` or `glab`, never an HTTP client. The facts sit behind\n * two vendors' auth stores and two API grammars, and the vendor CLI is the\n * trust boundary: manni never holds a token, never reads one, never prints\n * one. `gh` is on every GitHub-hosted runner and `glab` is one package\n * install on GitLab's (proposal 0040, decision 7).\n *\n * Two answers are deliberately *not* errors. A commit the host has no merged\n * change for (an open PR, a direct push, a commit that came in through\n * another repository) is `null`. A commit the host does not know at all is\n * `null` too. Everything else that goes wrong — a non-zero exit, a timeout,\n * an answer that is not JSON — throws `DocmetaError`, because a half-answer\n * read as \"no approvals\" would file a stale finding against a document that\n * was in fact reviewed.\n */\nimport { resolve as resolvePath } from \"node:path\";\nimport { DocmetaError } from \"../../types.js\";\nimport { ReviewCache, cachedClient } from \"./cache.js\";\nimport {\n BinMissing,\n DEFAULT_TIMEOUT_MS,\n commandLine,\n lastLine,\n run,\n type Run,\n type SpawnOptions,\n} from \"./spawn.js\";\nimport type {\n Approval,\n DerivedValue,\n ReviewClient,\n RemoteIdentity,\n MergedChange,\n SourceStatus,\n} from \"./types.js\";\n\nexport type { Approval, ReviewClient, RemoteIdentity, MergedChange } from \"./types.js\";\nexport type { SpawnOptions } from \"./spawn.js\";\n\n// ---------------------------------------------------------------------------\n// Origin → identity\n\n/**\n * The host and project an origin URL names, for the three spellings git\n * writes: `git@host:owner/repo.git`, `https://[user@]host/owner/repo[.git]`,\n * `ssh://git@host[:port]/owner/repo`. The project keeps every path segment,\n * because a GitLab namespace can nest (`group/sub/repo`). Anything else —\n * a local path, a bare host — is `null`. A local path is recognised before\n * the scp form is tried, because git reads `C:/mirrors/repo.git` as a\n * directory on drive C and the scp regex would read it as host `C`.\n */\nexport function parseOriginUrl(\n url: string,\n): { host: string; project: string } | null {\n const trimmed = url.trim();\n if (trimmed === \"\") return null;\n if (isLocalPath(trimmed)) return null;\n\n const scp = /^(?:[^@/:]+@)?([^/:]+):(?!\\/\\/)(.+)$/.exec(trimmed);\n if (scp) {\n const host = scp[1];\n const path = scp[2];\n if (host === undefined || path === undefined) return null;\n // A one-letter \"host\" is a DOS drive, whichever slash follows it.\n if (/^[A-Za-z]$/.test(host)) return null;\n return project(host, path);\n }\n\n let parsed: URL;\n try {\n parsed = new URL(trimmed);\n } catch {\n return null;\n }\n if (!/^(https?|ssh|git):$/.test(parsed.protocol)) return null;\n if (parsed.hostname === \"\") return null;\n return project(parsed.hostname, parsed.pathname);\n}\n\n/** Absolute, relative, or UNC: the spellings of a path that is not a URL. */\nfunction isLocalPath(s: string): boolean {\n return s.startsWith(\"/\") || s.startsWith(\"./\") || s.startsWith(\"../\") || s.startsWith(\"\\\\\\\\\");\n}\n\nfunction project(\n host: string,\n path: string,\n): { host: string; project: string } | null {\n const segments = path\n .replace(/\\.git$/, \"\")\n .split(\"/\")\n .filter((s) => s !== \"\");\n if (segments.length < 2) return null;\n return { host, project: segments.join(\"/\") };\n}\n\n/**\n * Which platform a host is, and so which CLI reaches it. A host whose name\n * says `github` (github.com, github.example.com) is GitHub; one that says\n * `gitlab` is GitLab. A host that says neither, such as `git.example.com`,\n * is decided by the config: when exactly one of the `github` and `gitlab`\n * sources is requested, that is the platform the operator named. Otherwise\n * the answer is null, and the caller reports it as a source that cannot\n * answer. Nothing is ever assumed: the `github` source applies to GitHub\n * and the `gitlab` source to GitLab, and neither stands in for the other.\n */\nexport function identityFromOrigin(\n host: string,\n project: string,\n requested?: readonly RemoteIdentity[\"kind\"][],\n): RemoteIdentity | null {\n const name = host.toLowerCase();\n if (name.includes(\"github\")) return { kind: \"github\", host, project };\n if (name.includes(\"gitlab\")) return { kind: \"gitlab\", host, project };\n const only = requested !== undefined && requested.length === 1 ? requested[0] : undefined;\n return only === undefined ? null : { kind: only, host, project };\n}\n\n/**\n * A client for an origin whose host names neither platform and whose config\n * does not say which it is. It answers nothing, and its status names the fix.\n */\nclass UnknownHostClient implements ReviewClient {\n constructor(private readonly host: string) {}\n detect(): Promise<RemoteIdentity | null> {\n return Promise.resolve(null);\n }\n status(): Promise<SourceStatus> {\n return Promise.resolve({\n available: false,\n reason: `the origin remote is ${this.host}, which names neither GitHub nor GitLab; list exactly one of github, gitlab in derive.sources to say which it is`,\n });\n }\n mergedChangeFor(): Promise<MergedChange | null> {\n return Promise.resolve(null);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Failure reading\n\n/** The HTTP status a `gh`/`glab` failure line carries, when it carries one. */\nfunction httpStatus(stderr: string): number | null {\n const m = /\\b(?:HTTP\\s+(\\d{3})|(\\d{3})\\s+Not\\s+Found)\\b/i.exec(stderr);\n const code = m?.[1] ?? m?.[2];\n return code === undefined ? null : Number(code);\n}\n\n/**\n * Whether a failed call is the host saying \"no such thing\" — a commit it\n * does not know (404, or GitHub's 422 \"No commit found for SHA\") — which is\n * an answer, not an error.\n */\nfunction isNotFound(r: Run): boolean {\n const status = httpStatus(r.stderr);\n return status === 404 || status === 422;\n}\n\n/**\n * The base for both CLIs: the same spawn, the same failure ladder, the same\n * status vocabulary. Subclasses supply the binary name and the lookups.\n */\nabstract class CliClient implements ReviewClient {\n protected abstract readonly tool: \"gh\" | \"glab\";\n\n constructor(\n protected readonly identity: RemoteIdentity | null,\n protected readonly spawnOpts: SpawnOptions,\n ) {}\n\n detect(): Promise<RemoteIdentity | null> {\n return Promise.resolve(this.identity);\n }\n\n async status(): Promise<SourceStatus> {\n if (this.identity === null) {\n return { available: false, reason: \"no origin remote to tell GitHub from GitLab\" };\n }\n const { host } = this.identity;\n let r: Run;\n try {\n r = await this.run([\"auth\", \"status\", \"--hostname\", host]);\n } catch (err) {\n if (err instanceof BinMissing) {\n return {\n available: false,\n reason: `${this.tool} is not on PATH (origin is ${host}); install ${this.tool} and run ${this.tool} auth login`,\n };\n }\n throw err;\n }\n if (r.timedOut) throw this.timeout([\"auth\", \"status\", \"--hostname\", host]);\n if (r.code !== 0) {\n return {\n available: false,\n reason: `${this.tool} is not authenticated for ${host}; run ${this.tool} auth login`,\n };\n }\n return { available: true };\n }\n\n async mergedChangeFor(sha: string): Promise<MergedChange | null> {\n if (this.identity === null) return null;\n return this.lookup(this.identity, sha);\n }\n\n protected abstract lookup(\n identity: RemoteIdentity,\n sha: string,\n ): Promise<MergedChange | null>;\n\n protected get bin(): string {\n return this.spawnOpts.bin ?? this.tool;\n }\n\n protected run(args: string[]): Promise<Run> {\n return run(this.bin, args, this.spawnOpts);\n }\n\n private timeout(args: string[]): DocmetaError {\n const ms = this.spawnOpts.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n return new DocmetaError(\n `${commandLine(this.tool, args)} timed out after ${ms}ms`,\n );\n }\n\n /**\n * Run a call whose stdout is JSON. A not-found answer is `null`; any other\n * failure throws, naming the command the user can re-run by hand. The\n * message quotes the tool's own name rather than `bin`, which under test\n * is `node`.\n */\n protected async json(args: string[]): Promise<unknown> {\n let r: Run;\n try {\n r = await this.run(args);\n } catch (err) {\n if (err instanceof BinMissing) {\n throw new DocmetaError(\n `${commandLine(this.tool, args)} failed: ${this.tool} is not on PATH`,\n );\n }\n throw err;\n }\n const cmd = commandLine(this.tool, args);\n if (r.timedOut) throw this.timeout(args);\n // A truncated answer must not be read as the whole one: half a page of\n // reviews would file a stale finding against a document that was\n // reviewed, which is the half-answer this class refuses everywhere.\n if (r.tooLarge) {\n throw new DocmetaError(`${cmd} wrote more output than manni will read`);\n }\n if (r.code !== 0) {\n if (isNotFound(r)) return null;\n const detail = lastLine(r.stderr) || lastLine(r.stdout);\n const exit = r.code === null ? \"signal\" : `exit ${r.code}`;\n throw new DocmetaError(\n `${cmd} failed (${exit})${detail === \"\" ? \"\" : `: ${detail}`}`,\n );\n }\n try {\n return JSON.parse(r.stdout) as unknown;\n } catch {\n throw new DocmetaError(`${cmd} did not return JSON`);\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Answer shapes, read defensively\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nfunction items(v: unknown): Record<string, unknown>[] {\n return Array.isArray(v) ? v.filter(isRecord) : [];\n}\n\nfunction numberOf(v: unknown): number | null {\n return typeof v === \"number\" && Number.isInteger(v) ? v : null;\n}\n\nfunction stringOf(v: unknown): string | null {\n return typeof v === \"string\" && v !== \"\" ? v : null;\n}\n\n/** A field that is present and a string, present and null, or absent. */\ntype Tri = string | null | undefined;\n\nfunction timestampOf(v: unknown): Tri {\n if (v === undefined) return undefined;\n return stringOf(v);\n}\n\n/**\n * `claude[bot]` (REST) and `claude` (GraphQL) are one reviewer. The stripped\n * form is the dedupe key; the value keeps whichever spelling the latest\n * approval carried.\n */\nfunction normalizeLogin(login: string): string {\n return login.replace(/\\[bot\\]$/, \"\");\n}\n\n/** `APPROVED` only, the latest per reviewer, oldest approval first. */\nfunction latestApprovals(\n reviews: readonly { login: string; state: string; submittedAt: string }[],\n): Approval[] {\n const latest = new Map<string, Approval>();\n for (const r of reviews) {\n if (r.state !== \"APPROVED\") continue;\n const key = normalizeLogin(r.login);\n const seen = latest.get(key);\n if (seen === undefined || r.submittedAt > seen.submittedAt) {\n latest.set(key, { login: r.login, submittedAt: r.submittedAt });\n }\n }\n return byTime([...latest.values()]);\n}\n\nfunction byTime(approvals: readonly Approval[]): Approval[] {\n return [...approvals].sort((a, b) =>\n a.submittedAt < b.submittedAt ? -1 : a.submittedAt > b.submittedAt ? 1 : 0,\n );\n}\n\n// ---------------------------------------------------------------------------\n// GitHub\n\n/**\n * GitHub through `gh`. Every call carries `--hostname` (or `-R host/project`)\n * so a GHES origin is reached even when `gh`'s default host is github.com.\n *\n * - `gh api --hostname <host> repos/<project>/commits/<sha>/pulls`\n * - if empty: `gh pr list --search <sha> --state merged --json number,mergedAt -R <host>/<project>`\n * (a squash-merged commit's original sha is only findable through search,\n * and a commit that came in through another repository is `[]` here, which\n * is a legitimate non-error)\n * - `gh api --hostname <host> repos/<project>/pulls/<n>` only when the list\n * item does not say whether it merged\n * - `gh api --hostname <host> repos/<project>/pulls/<n>/reviews?per_page=100`\n */\nexport class GitHubClient extends CliClient {\n protected readonly tool = \"gh\";\n\n protected async lookup(\n identity: RemoteIdentity,\n sha: string,\n ): Promise<MergedChange | null> {\n const { host, project } = identity;\n const api = (endpoint: string): Promise<unknown> =>\n this.json([\"api\", \"--hostname\", host, endpoint]);\n\n let candidates = items(await api(`repos/${project}/commits/${sha}/pulls`)).map(\n (p) => ({ number: numberOf(p.number), mergedAt: timestampOf(p.merged_at) }),\n );\n if (candidates.length === 0) {\n const found = await this.json([\n \"pr\", \"list\", \"--search\", sha, \"--state\", \"merged\",\n \"--json\", \"number,mergedAt\", \"-R\", `${host}/${project}`,\n ]);\n candidates = items(found).map((p) => ({\n number: numberOf(p.number),\n mergedAt: timestampOf(p.mergedAt),\n }));\n }\n\n for (const c of candidates) {\n if (c.number === null) continue;\n let mergedAt = c.mergedAt;\n if (mergedAt === undefined) {\n const pr = await api(`repos/${project}/pulls/${c.number}`);\n mergedAt = isRecord(pr) ? (stringOf(pr.merged_at) ?? null) : null;\n }\n if (mergedAt === null) continue;\n\n // The reviews endpoint lists oldest first, 100 per page, with no sort\n // parameter, so a long-lived PR's latest approvals sit past the first\n // page. Walk pages until one comes back short.\n const raw: Record<string, unknown>[] = [];\n for (let page = 1; ; page += 1) {\n const batch = items(\n await api(`repos/${project}/pulls/${c.number}/reviews?per_page=100&page=${page}`),\n );\n raw.push(...batch);\n if (batch.length < 100) break;\n }\n const reviews = raw\n .map((r) => ({\n login: isRecord(r.user) ? stringOf(r.user.login) : null,\n state: stringOf(r.state),\n submittedAt: stringOf(r.submitted_at),\n }))\n .filter(\n (r): r is { login: string; state: string; submittedAt: string } =>\n r.login !== null && r.state !== null && r.submittedAt !== null,\n );\n return { id: c.number, mergedAt, approvals: latestApprovals(reviews) };\n }\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// GitLab\n\n/**\n * GitLab through `glab`. `:fullpath` is substituted by glab from the current\n * repository, which is why the client runs from the checkout.\n *\n * - `glab api --hostname <host> projects/:fullpath/repository/commits/<sha>/merge_requests`\n * - `glab api --hostname <host> projects/:fullpath/merge_requests/<iid>/approvals`\n *\n * GitLab records who approved but not when, so every approval is stamped\n * with the MR's `merged_at`; `deriveFromReviews` says so in the evidence.\n */\nexport class GitLabClient extends CliClient {\n protected readonly tool = \"glab\";\n\n protected async lookup(\n identity: RemoteIdentity,\n sha: string,\n ): Promise<MergedChange | null> {\n const { host } = identity;\n const api = (endpoint: string): Promise<unknown> =>\n this.json([\"api\", \"--hostname\", host, endpoint]);\n\n const merged = items(\n await api(`projects/:fullpath/repository/commits/${sha}/merge_requests`),\n )\n .map((mr) => ({ iid: numberOf(mr.iid), mergedAt: stringOf(mr.merged_at) }))\n .find(\n (mr): mr is { iid: number; mergedAt: string } =>\n mr.iid !== null && mr.mergedAt !== null,\n );\n if (merged === undefined) return null;\n\n const answer = await api(`projects/:fullpath/merge_requests/${merged.iid}/approvals`);\n const approvedBy = isRecord(answer) ? items(answer.approved_by) : [];\n const approvals: Approval[] = [];\n const seen = new Set<string>();\n for (const entry of approvedBy) {\n const login = isRecord(entry.user) ? stringOf(entry.user.username) : null;\n if (login === null) continue;\n const key = normalizeLogin(login);\n if (seen.has(key)) continue;\n seen.add(key);\n approvals.push({ login, submittedAt: merged.mergedAt });\n }\n return { id: merged.iid, mergedAt: merged.mergedAt, approvals };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Assembly\n\n/**\n * The client for the repository at `root`: origin read with\n * `git remote get-url origin`, the CLI chosen by `identityFromOrigin`, the\n * result wrapped in the on-disk cache. No origin (or no git) yields a client\n * whose `status()` says so; nothing throws here, because \"no host\" is a\n * source being unavailable, and that is reported where sources are reported.\n *\n * The CLI is spawned in `root`, not in the caller's `cwd`: `glab` fills in\n * `:fullpath` from the repository it runs in, and `gh` detects the\n * repository the same way, so the child must run from the checkout this\n * client answers for. `spawn.cwd` is the test seam that overrides that.\n */\nexport async function createReviewClient(\n root: string,\n opts: {\n cwd: string;\n cache: boolean;\n cacheDir: string;\n spawn?: Partial<SpawnOptions>;\n /** The review sources the run requested; decides a host that names neither platform. */\n requested?: readonly RemoteIdentity[\"kind\"][];\n },\n): Promise<ReviewClient> {\n const spawnOpts: SpawnOptions = { ...opts.spawn, cwd: opts.spawn?.cwd ?? root };\n const origin = await originUrl(root);\n const parsed = origin === null ? null : parseOriginUrl(origin);\n const identity =\n parsed === null ? null : identityFromOrigin(parsed.host, parsed.project, opts.requested);\n if (parsed !== null && identity === null) return new UnknownHostClient(parsed.host);\n const client =\n identity?.kind === \"gitlab\"\n ? new GitLabClient(identity, spawnOpts)\n : new GitHubClient(identity, spawnOpts);\n const cache = new ReviewCache(resolvePath(root, opts.cacheDir), opts.cache);\n return cachedClient(client, cache, identity);\n}\n\n/** `git remote get-url origin`, or null when there is no origin or no git. */\nasync function originUrl(root: string): Promise<string | null> {\n try {\n const r = await run(\"git\", [\"remote\", \"get-url\", \"origin\"], { cwd: root });\n if (r.code !== 0 || r.timedOut || r.tooLarge) return null;\n return stringOf(r.stdout.trim());\n } catch {\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// The source\n\nexport interface ReviewSourceInput {\n label: string;\n /** The newest body-changing commit; `null` for a working-tree document. */\n sha: string | null;\n}\n\nexport interface ReviewFacts {\n \"reviewed-by\": DerivedValue | null;\n \"last-reviewed\": DerivedValue | null;\n}\n\nexport interface ReviewSourceResult {\n status: SourceStatus;\n /** By label. Empty when the source is unavailable. */\n records: Map<string, ReviewFacts>;\n}\n\nconst NOTHING: ReviewFacts = { \"reviewed-by\": null, \"last-reviewed\": null };\n\n/**\n * `reviewed-by` is every approver of the merged change, in approval order,\n * and every fact names the source of the host it came from, `github` or `gitlab`;\n * `last-reviewed` is the UTC date of the latest approval. A document with no\n * commit, no merged change, or a change nobody approved derives `null` for\n * both. One host lookup per distinct sha, however many documents share it.\n *\n * An unavailable client is reported and never called: `status.reason` names\n * the fix, and the caller decides whether that fails the run.\n */\nexport async function deriveFromReviews(\n inputs: readonly ReviewSourceInput[],\n client: ReviewClient,\n): Promise<ReviewSourceResult> {\n const records = new Map<string, ReviewFacts>();\n const status = await client.status();\n if (!status.available) return { status, records };\n\n const identity = await client.detect();\n // `status()` answering `available` means the client found its host, so both\n // built-in clients return an identity here. The fallback serves only a\n // custom `ReviewClient` that breaks that promise, and it attributes every\n // fact to GitHub. Such a client should return an identity from `detect()`.\n const kind = identity?.kind ?? \"github\";\n const bySha = new Map<string, Promise<MergedChange | null>>();\n const changeFor = (sha: string): Promise<MergedChange | null> => {\n let pending = bySha.get(sha);\n if (pending === undefined) {\n pending = client.mergedChangeFor(sha);\n bySha.set(sha, pending);\n }\n return pending;\n };\n\n for (const input of inputs) {\n if (input.sha === null) {\n records.set(input.label, NOTHING);\n continue;\n }\n const change = await changeFor(input.sha);\n records.set(input.label, factsFrom(change, kind));\n }\n return { status, records };\n}\n\nfunction factsFrom(change: MergedChange | null, kind: RemoteIdentity[\"kind\"]): ReviewFacts {\n if (change === null || change.approvals.length === 0) return NOTHING;\n // Sorted here too: a `ReviewClient` from outside this module makes no\n // ordering promise, and the field order is what the reader sees.\n const ordered = byTime(change.approvals);\n const latest = ordered.at(-1);\n if (latest === undefined) return NOTHING;\n const evidence = kind === \"gitlab\" ? `gitlab MR !${change.id}` : `github PR #${change.id}`;\n const dateEvidence =\n kind === \"gitlab\"\n ? `${evidence} (merge date; GitLab records no approval time)`\n : evidence;\n return {\n \"reviewed-by\": {\n value: ordered.map((a) => a.login),\n source: kind,\n evidence,\n },\n \"last-reviewed\": {\n value: utcDate(latest.submittedAt),\n source: kind,\n evidence: dateEvidence,\n },\n };\n}\n\n/** `YYYY-MM-DD` in UTC; the timestamp's own text when it does not parse. */\nfunction utcDate(iso: string): string {\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return iso;\n return new Date(ms).toISOString().slice(0, 10);\n}\n","/**\n * The git source of the derived channel (proposal 0040): what history can\n * state about a document's birth, its last body change, who wrote it and who\n * reviewed it.\n *\n * Documents are grouped by the repository that contains them, as\n * `gitignore.ts` groups candidates, and each root is asked once. A root's\n * history is read in one of two forms that produce the same `FileHistory`:\n * per-file `git log --follow` for a small run, because `--follow` is what\n * carries `created` across a rename and it forbids more than one pathspec;\n * one whole-repository `git log --raw -M` walk otherwise, with renames\n * followed backwards here. The judge on top of either form is the same.\n *\n * A body change is a change outside the metadata block, so a frontmatter\n * sweep does not move `last-updated`. Blobs are compared by their bodies\n * with line endings normalised, because `core.autocrlf` rewrites a blob on\n * the way in and out of the index and that is not an edit.\n *\n * Availability is a verdict, not an exception (decision 6): git missing, no\n * repository, or a shallow checkout report `available: false` with the fix.\n */\nimport { constants as bufferConstants } from \"node:buffer\";\nimport { spawn, type ChildProcessWithoutNullStreams } from \"node:child_process\";\nimport { availableParallelism } from \"node:os\";\nimport { dirname, extname, isAbsolute, posix, relative, sep } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { mapConcurrent } from \"../../../shared/concurrency.js\";\nimport { findGitRoot } from \"../../../shared/git-root.js\";\nimport { locateFrontmatter } from \"../../extractors/frontmatter.js\";\nimport {\n extractorByName,\n extractorForExtension,\n} from \"../../extractors/index.js\";\nimport type { ExtractedMetadata, MetadataExtractor } from \"../../types.js\";\nimport { toJsonText } from \"../json-text.js\";\nimport { parseLines, splitLines, toFileLines } from \"../../../shared/pin.js\";\nimport {\n attributeRange,\n DEFAULT_MACHINES,\n deriveProvenance,\n machineIdentity,\n parseLinePorcelain,\n provenanceEntries,\n readProvenancePage,\n ZERO_SHA,\n type BlameLine,\n type CommitEvidence,\n type ProvenanceDerivation,\n type ProvenanceEntry,\n} from \"./provenance.js\";\nimport {\n PROVENANCE_FIELD,\n STAMPED_DATE_FIELDS,\n type DeriveInput,\n type DerivedValue,\n type ManifestRef,\n type SourceStatus,\n type StampedDateField,\n} from \"./types.js\";\n\n/** Facts git can state about one document. Every field is null when git answered but has no fact. */\nexport interface GitFacts {\n created: DerivedValue | null;\n \"last-updated\": DerivedValue | null;\n authors: DerivedValue | null;\n /** From `Reviewed-by` trailers only. */\n \"reviewed-by\": DerivedValue | null;\n /** From `Reviewed-by` trailers only. */\n \"last-reviewed\": DerivedValue | null;\n /**\n * The machine-written body ranges (proposal 0046), from blame and the\n * commits it names: the entry list as a page would carry it, or null when\n * no line names a machine, and when provenance was not requested.\n */\n provenance: DerivedValue | null;\n /**\n * The derivation behind `provenance`, per body line, which the comparison\n * with a page's stamp reads. Present exactly when provenance was requested.\n */\n provenanceDerivation?: ProvenanceDerivation;\n /** Full sha of the newest body-changing commit, for the review sources; null when uncommitted or none. */\n lastBodyCommit: string | null;\n /** Repository root the document lives in, absolute, native separators. */\n root: string;\n}\n\nexport interface GitSourceOptions {\n cwd: string;\n now: () => Date;\n /** Runs with more inputs per root than this take the bulk walk. Test seam; default 32. */\n bulkThreshold?: number;\n /**\n * Most bytes one git process may write to stdout before the root is\n * reported too large to read. Test seam; default `MAX_GIT_OUTPUT_BYTES`.\n */\n maxOutputBytes?: number;\n /**\n * The fields the run asks for. Blame runs only when it names\n * `provenance`, which is the per-field gating 0040 already has.\n */\n fields?: readonly string[];\n /** `--generated-by` or `MANNI_GENERATED_BY`: the machine uncommitted lines go to (rule 1). */\n generatedBy?: string;\n /** `derive.machines`; `DEFAULT_MACHINES` when absent. */\n machines?: readonly string[];\n}\n\nexport interface GitSourceResult {\n status: SourceStatus;\n /** Keyed by `DeriveInput.label`. A document outside any repository is absent. */\n records: Map<string, GitFacts>;\n}\n\nconst DEFAULT_BULK_THRESHOLD = 32;\nconst NULL_SHA = \"0\".repeat(40);\n\n/**\n * The whole of one git process's stdout is held in memory and decoded in one\n * pass; streaming the log is out of scope for now. A history past this cap\n * is refused rather than decoded: 512 MiB, or V8's string limit where that\n * is lower, so the cap itself is what stops the run and not an\n * `ERR_STRING_TOO_LONG` from inside `Buffer#toString`.\n */\nconst MAX_GIT_OUTPUT_BYTES = Math.min(\n 512 * 1024 * 1024,\n bufferConstants.MAX_STRING_LENGTH,\n);\n\n/** A root whose history cannot be held in memory; caught by `deriveFromGit`. */\nclass HistoryTooLarge extends Error {}\n\n/**\n * `git cat-file --batch` exited non-zero: a corrupt object, a missing pack,\n * lock contention. An empty blob map would read every body as empty and\n * every history entry as unchanged, which is the false green the channel\n * refuses, so it is a failed root like a shallow clone.\n */\nclass BlobsUnreadable extends Error {\n constructor(readonly detail: string) {\n super(detail);\n }\n}\n\n/**\n * `git blame` exited non-zero for a file that HEAD has. A file HEAD lacks\n * (untracked, deleted and recreated, or in a repository with no commits yet)\n * is not this: all of its lines are uncommitted, and blame has nothing to add.\n * `detail` is git's own stderr.\n */\nclass BlameUnreadable extends Error {\n constructor(\n readonly rel: string,\n readonly detail: string,\n ) {\n super(rel);\n }\n}\n\n/** One commit that touched a document, as either walk form reports it. */\ninterface FileHistory {\n sha: string;\n /** `%aI`: ISO 8601 in the author's own offset. */\n authorDate: string;\n authorName: string;\n authorEmail: string;\n /** `Co-authored-by` trailer values, `Name <email>` form. */\n coAuthors: string[];\n /** `Reviewed-by` trailer values, as written. */\n reviewedBy: string[];\n /** `Generated-by` trailer values, as written (proposal 0046). */\n generatedBy: string[];\n oldBlob: string | null;\n newBlob: string | null;\n pathAtCommit: string;\n /** A merge's parents after the first; empty for any other commit. */\n otherParents: string[];\n /**\n * The document's blob at each of `otherParents`, null where that parent\n * did not hold it. Read after the walk, by `readOtherParentBlobs`.\n */\n otherParentBlobs: (string | null)[];\n}\n\n/**\n * Content outside the metadata block: for a fenced document the block\n * `[openStart, closeEnd)` is dropped, so a BOM ahead of it survives; anything\n * else is the whole content. Exported for the orchestrator and tests.\n */\nexport function bodyOf(content: string, fenced: boolean | undefined): string {\n if (fenced !== true) return content;\n const loc = locateFrontmatter(content);\n if (!loc) return content;\n return content.slice(0, loc.openStart) + content.slice(loc.closeEnd);\n}\n\n/**\n * Never throws for availability: git missing, no repository for any input,\n * a shallow clone, or a history too large to read report\n * `status.available: false` with a `reason` that names the fix, and an\n * empty map. One root that cannot answer makes the source unavailable for\n * the whole run, as `deriveReviewsByRoot` rules: a walk that answered for\n * some roots and silently dropped the rest would read as green for\n * documents it never looked at. An input outside any repository is not a\n * failing root; it is simply absent from the records.\n */\nexport async function deriveFromGit(\n inputs: readonly DeriveInput[],\n opts: GitSourceOptions,\n): Promise<GitSourceResult> {\n const records = new Map<string, GitFacts>();\n const byRoot = groupByRoot(inputs);\n if (byRoot.size === 0) {\n return {\n status: {\n available: false,\n reason: \"no git repository contains the documents\",\n },\n records,\n };\n }\n\n const threshold = opts.bulkThreshold ?? DEFAULT_BULK_THRESHOLD;\n const machines = opts.machines ?? DEFAULT_MACHINES;\n const wantsProvenance = opts.fields?.includes(PROVENANCE_FIELD) ?? false;\n const maxBytes = opts.maxOutputBytes ?? MAX_GIT_OUTPUT_BYTES;\n const parse = yamlOnce();\n const reasons: string[] = [];\n for (const [root, bucket] of byRoot) {\n const run: GitRun = (args, stdin) => runGit(args, root, stdin, maxBytes);\n const shallow = await run([\"rev-parse\", \"--is-shallow-repository\"]);\n if (shallow.missing) {\n return {\n status: { available: false, reason: \"git is not on PATH\" },\n records: new Map(),\n };\n }\n if (shallow.code !== 0) {\n reasons.push(`git could not read the repository at ${root}`);\n continue;\n }\n if (text(shallow).trim() === \"true\") {\n reasons.push(\n `this checkout is shallow; use actions/checkout with fetch-depth: 0 (${root})`,\n );\n continue;\n }\n\n try {\n const found = await histories(\n run,\n bucket.map((e) => e.rel),\n threshold,\n );\n if (found === null) {\n reasons.push(`git could not read the history at ${root}`);\n continue;\n }\n await readOtherParentBlobs(run, found);\n const blobs = await fetchBlobs(run, neededBlobs(found));\n if (!(await followTakenBodies(run, bucket, found, blobs, threshold))) {\n reasons.push(`git could not read the history at ${root}`);\n continue;\n }\n const manifestStamps = await stampsInManifests(run, root, bucket, found, blobs, parse);\n\n const facts = bucket.map((entry) =>\n judge(\n entry.input,\n root,\n found.get(entry.rel) ?? [],\n blobs,\n opts.now,\n machines,\n manifestStamps.get(entry.input.label),\n ),\n );\n if (wantsProvenance) {\n // Blame is one git process a page, and no page's depends on another's.\n // Run a few at once: one at a time, process start-up dominates, worst\n // on Windows. What the blames name is then read for the whole root at\n // once. Results keep input order whatever finishes first.\n const pages = await mapConcurrent(bucket, GIT_CONCURRENCY, async (entry) => ({\n entry,\n blame: await blameOf(run, entry.rel, entry.input.content),\n history: found.get(entry.rel) ?? [],\n }));\n const evidence = await commitEvidence(run, root, pages, blobs, parse);\n const provenanceRun: ProvenanceRun = {\n machines,\n ...(opts.generatedBy !== undefined ? { generatedBy: opts.generatedBy } : {}),\n };\n pages.forEach((page, i) => {\n const judged = facts[i];\n const commits = evidence[i];\n if (judged === undefined || commits === undefined) return;\n const derived = provenanceFor(page.entry, page.blame, commits, provenanceRun);\n judged.provenance = derived.value;\n judged.provenanceDerivation = derived.derivation;\n });\n }\n bucket.forEach((entry, i) => {\n const judged = facts[i];\n if (judged !== undefined) records.set(entry.input.label, judged);\n });\n } catch (err) {\n if (err instanceof BlobsUnreadable) {\n reasons.push(`git cat-file could not read the history (${root}): ${err.detail}`);\n continue;\n }\n if (err instanceof BlameUnreadable) {\n const why = err.detail === \"\" ? \"\" : `: ${err.detail}`;\n reasons.push(`git blame could not read ${err.rel} (${root})${why}`);\n continue;\n }\n if (!(err instanceof HistoryTooLarge)) throw err;\n reasons.push(`git history is too large to read in one pass (${root})`);\n continue;\n }\n }\n\n if (reasons.length > 0) {\n return {\n status: { available: false, reason: reasons.join(\"; \") },\n records: new Map(),\n };\n }\n return { status: { available: true }, records };\n}\n\n// ---------------------------------------------------------------------------\n// Grouping\n\ninterface RootEntry {\n input: DeriveInput;\n /** Root-relative, forward slashes: how git names the path. */\n rel: string;\n}\n\nfunction groupByRoot(inputs: readonly DeriveInput[]): Map<string, RootEntry[]> {\n const rootOf = new Map<string, string | null>();\n const byRoot = new Map<string, RootEntry[]>();\n for (const input of inputs) {\n const dir = dirname(input.absPath);\n let root = rootOf.get(dir);\n if (root === undefined) {\n root = findGitRoot(dir);\n rootOf.set(dir, root);\n }\n if (root === null) continue;\n const rel = relative(root, input.absPath).split(sep).join(\"/\");\n const bucket = byRoot.get(root);\n if (bucket) bucket.push({ input, rel });\n else byRoot.set(root, [{ input, rel }]);\n }\n return byRoot;\n}\n\n// ---------------------------------------------------------------------------\n// History walks\n\n/**\n * Record format: one `\\x1e`-led header per commit, its fields `\\0`-separated,\n * trailer values `\\x1f`-separated. `--raw` lines follow each header. `-z` is\n * deliberately absent: it makes the record boundary ambiguous, where `\\x1e`\n * cannot appear in a sha, a date, or a raw line. `--no-abbrev` because\n * `--raw` shortens blob shas by default, and `cat-file` wants the full ones.\n * `unfold` because a trailer may wrap onto an indented continuation line,\n * and the header is read up to its first newline: folded, the rest of the\n * header would be taken for raw lines and the value split in two.\n */\nconst RECORD_FORMAT =\n \"--format=%x1e%H%x00%aI%x00%an%x00%ae%x00\" +\n \"%(trailers:key=Co-authored-by,valueonly,unfold,separator=%x1f)%x00\" +\n \"%(trailers:key=Reviewed-by,valueonly,unfold,separator=%x1f)%x00\" +\n \"%(trailers:key=Generated-by,valueonly,unfold,separator=%x1f)%x00\" +\n \"%P\";\n\n/**\n * `--diff-merges=first-parent` because `--raw` prints nothing for a merge by\n * default. A body two branches both edited exists only in the merge that\n * combined them, so without the merge's own diff no commit in the history\n * holds that blob, and the committed body reads as uncommitted. First parent\n * is also how a commit's prior state is read here (`<sha>^`). A merge whose\n * body another parent already held did not produce it, so the judge passes\n * over it, and the commit that wrote the body on that side dates it. A pull\n * request's merge ref is the common case: the base is its first parent.\n */\nconst LOG_ARGS = [\n \"-c\",\n \"core.quotePath=false\",\n \"log\",\n \"--raw\",\n \"--diff-merges=first-parent\",\n \"-M\",\n \"--no-abbrev\",\n RECORD_FORMAT,\n];\n\n/** Either walk form, by how many paths it reads. */\nfunction histories(\n run: GitRun,\n rels: readonly string[],\n threshold: number,\n rev = \"HEAD\",\n): Promise<Map<string, FileHistory[]> | null> {\n return rels.length <= threshold\n ? perFileHistories(run, rels, rev)\n : bulkHistories(run, rels, rev);\n}\n\n/** The per-file form: `--follow` carries the path across renames itself. */\nasync function perFileHistories(\n run: GitRun,\n rels: readonly string[],\n rev: string,\n): Promise<Map<string, FileHistory[]> | null> {\n const found = new Map<string, FileHistory[]>();\n for (const rel of rels) {\n const out = await run([...LOG_ARGS, rev, \"--follow\", \"--\", pathspec(rel)]);\n if (out.tooLarge) throw new HistoryTooLarge();\n if (out.code !== 0) {\n if (await isUnbornHead(run)) return found;\n return null;\n }\n // `--follow` already walked the rename; `attribute` still applies so the\n // rename commit's own raw line is read the same way the bulk form reads it.\n const attributed = attribute(parseLog(text(out)), [rel]);\n found.set(rel, attributed.get(rel) ?? []);\n }\n return found;\n}\n\n/** The bulk form: one walk, every path attributed and followed here. */\nasync function bulkHistories(\n run: GitRun,\n rels: readonly string[],\n rev: string,\n): Promise<Map<string, FileHistory[]> | null> {\n const out = await run([...LOG_ARGS, rev]);\n if (out.tooLarge) throw new HistoryTooLarge();\n if (out.code !== 0) {\n if (await isUnbornHead(run)) return new Map();\n return null;\n }\n return attribute(parseLog(text(out)), [...rels]);\n}\n\n/**\n * A page whose newest body change is a merge that took the body whole from\n * another parent is read as that parent reads it. Its history from that\n * parent replaces the merge and everything older, so the commit that wrote\n * the body dates it, under whatever path it had on that side. The commits\n * newer than the merge are kept: none of them changed the body. Pages that\n * share a parent are walked together, and the walk repeats while the newest\n * body change on the new side is itself such a merge. Each round walks\n * strictly older commits, so it ends.\n */\nasync function followTakenBodies(\n run: GitRun,\n bucket: readonly RootEntry[],\n found: Map<string, FileHistory[]>,\n blobs: Map<string, string>,\n threshold: number,\n): Promise<boolean> {\n for (;;) {\n const byParent = new Map<string, { rel: string; keep: FileHistory[]; path: string }[]>();\n for (const entry of bucket) {\n const history = found.get(entry.rel) ?? [];\n const taken = takenMerge(entry.input.extracted.fenced, history, blobs);\n if (taken === undefined) continue;\n const group = byParent.get(taken.parent) ?? [];\n group.push({ rel: entry.rel, keep: history.slice(0, taken.index), path: taken.path });\n byParent.set(taken.parent, group);\n }\n if (byParent.size === 0) return true;\n\n const walked = new Map<string, FileHistory[]>();\n for (const [parent, group] of byParent) {\n const paths = [...new Set(group.map((g) => g.path))];\n const side = await histories(run, paths, threshold, parent);\n if (side === null) return false;\n for (const g of group) {\n const tail = side.get(g.path) ?? [];\n walked.set(g.rel, tail);\n found.set(g.rel, [...g.keep, ...tail]);\n }\n }\n await readOtherParentBlobs(run, walked);\n const missing = new Set([...neededBlobs(walked)].filter((sha) => !blobs.has(sha)));\n for (const [sha, content] of await fetchBlobs(run, missing)) blobs.set(sha, content);\n }\n}\n\n/**\n * The newest body change in `history`, when it is a merge whose body another\n * parent already held: its position, that parent, and the page's path there.\n */\nfunction takenMerge(\n fenced: boolean | undefined,\n history: readonly FileHistory[],\n blobs: ReadonlyMap<string, string>,\n): { index: number; parent: string; path: string } | undefined {\n const blobBody = (sha: string | null): string | null =>\n sha === null ? null : bodyOf(blobs.get(sha) ?? \"\", fenced);\n const index = history.findIndex((h) => !sameBody(blobBody(h.newBlob), blobBody(h.oldBlob)));\n const newest = history[index];\n if (newest === undefined) return undefined;\n const body = blobBody(newest.newBlob);\n const k = newest.otherParentBlobs.findIndex((b) => b !== null && sameBody(body, blobBody(b)));\n const parent = newest.otherParents[k];\n if (k === -1 || parent === undefined) return undefined;\n return { index, parent, path: newest.pathAtCommit };\n}\n\n/** A path with glob characters is named literally, as `gitignore.ts` does. */\nfunction pathspec(rel: string): string {\n return /[*?[\\]]/.test(rel) ? `:(literal)${rel}` : rel;\n}\n\n/** A repository with no commits yet has no history rather than a broken one. */\nasync function isUnbornHead(run: GitRun): Promise<boolean> {\n const out = await run([\"rev-parse\", \"--verify\", \"--quiet\", \"HEAD^{commit}\"]);\n return !out.missing && out.code !== 0;\n}\n\ninterface RawEntry {\n status: string;\n oldBlob: string;\n newBlob: string;\n oldPath: string;\n newPath: string;\n}\n\ninterface LogRecord {\n sha: string;\n authorDate: string;\n authorName: string;\n authorEmail: string;\n coAuthors: string[];\n reviewedBy: string[];\n generatedBy: string[];\n /** `%P`: the commit's parents, first parent first. */\n parents: string[];\n raw: RawEntry[];\n}\n\nfunction parseLog(text: string): LogRecord[] {\n const records: LogRecord[] = [];\n for (const chunk of text.split(\"\\x1e\")) {\n if (chunk === \"\") continue;\n const nl = chunk.indexOf(\"\\n\");\n const header = nl === -1 ? chunk : chunk.slice(0, nl);\n const fields = header.split(\"\\0\");\n const sha = fields[0];\n if (sha === undefined || sha === \"\") continue;\n const raw: RawEntry[] = [];\n if (nl !== -1) {\n for (const line of chunk.slice(nl + 1).split(\"\\n\")) {\n const entry = parseRawLine(line);\n if (entry) raw.push(entry);\n }\n }\n records.push({\n sha,\n authorDate: fields[1] ?? \"\",\n authorName: fields[2] ?? \"\",\n authorEmail: fields[3] ?? \"\",\n coAuthors: splitTrailers(fields[4]),\n reviewedBy: splitTrailers(fields[5]),\n generatedBy: splitTrailers(fields[6]),\n parents: (fields[7] ?? \"\").trim().split(\" \").filter((p) => p !== \"\"),\n raw,\n });\n }\n return records;\n}\n\nfunction splitTrailers(field: string | undefined): string[] {\n if (field === undefined || field === \"\") return [];\n return field\n .split(\"\\x1f\")\n .map((s) => s.trim())\n .filter((s) => s !== \"\");\n}\n\n/**\n * `:<oldmode> <newmode> <oldsha> <newsha> <status>\\t<path>`, or with two\n * paths after `R`/`C`. A path git still had to quote (a control character\n * or a backslash, even with `core.quotePath=false`) is C-unquoted.\n */\nfunction parseRawLine(line: string): RawEntry | null {\n if (!line.startsWith(\":\")) return null;\n const tab = line.indexOf(\"\\t\");\n if (tab === -1) return null;\n const meta = line.slice(1, tab).split(\" \");\n const oldBlob = meta[2];\n const newBlob = meta[3];\n const status = meta[4];\n if (oldBlob === undefined || newBlob === undefined || status === undefined) {\n return null;\n }\n const paths = line.slice(tab + 1).split(\"\\t\").map(unquotePath);\n const first = paths[0];\n if (first === undefined) return null;\n const second = paths[1];\n const renamed = status.startsWith(\"R\") || status.startsWith(\"C\");\n return {\n status,\n oldBlob,\n newBlob,\n oldPath: first,\n newPath: renamed && second !== undefined ? second : first,\n };\n}\n\nfunction unquotePath(p: string): string {\n if (p.length < 2 || !p.startsWith('\"') || !p.endsWith('\"')) return p;\n const inner = p.slice(1, -1);\n const bytes: number[] = [];\n for (let i = 0; i < inner.length; i += 1) {\n const ch = inner[i];\n if (ch !== \"\\\\\") {\n bytes.push(...Buffer.from(ch ?? \"\", \"utf8\"));\n continue;\n }\n const next = inner[i + 1];\n if (next === undefined) break;\n const octal = /^[0-7]{3}/.exec(inner.slice(i + 1));\n if (octal) {\n bytes.push(parseInt(octal[0], 8));\n i += 3;\n continue;\n }\n const simple: Record<string, number> = {\n a: 7, b: 8, t: 9, n: 10, v: 11, f: 12, r: 13, '\"': 34, \"\\\\\": 92,\n };\n const code = simple[next];\n if (code === undefined) bytes.push(...Buffer.from(next, \"utf8\"));\n else bytes.push(code);\n i += 1;\n }\n return Buffer.from(bytes).toString(\"utf8\");\n}\n\n/**\n * Attribute raw lines to the wanted paths, newest first, following a rename\n * backwards: after the commit that renamed `old` to `new`, the file is\n * looked for under `old`. A path deleted and later re-added is tracked\n * through the deletion, since the re-add is its newest history.\n */\nfunction attribute(\n records: LogRecord[],\n wanted: string[],\n): Map<string, FileHistory[]> {\n const histories = new Map<string, FileHistory[]>();\n // The path each wanted document is currently known by, walking backwards.\n const tracked = new Map<string, string>();\n for (const rel of wanted) {\n histories.set(rel, []);\n tracked.set(rel, rel);\n }\n for (const record of records) {\n if (record.raw.length === 0) continue;\n const byNewPath = new Map<string, RawEntry>();\n for (const entry of record.raw) byNewPath.set(entry.newPath, entry);\n for (const [rel, current] of tracked) {\n const entry = byNewPath.get(current);\n if (!entry) continue;\n histories.get(rel)?.push({\n sha: record.sha,\n authorDate: record.authorDate,\n authorName: record.authorName,\n authorEmail: record.authorEmail,\n coAuthors: record.coAuthors,\n reviewedBy: record.reviewedBy,\n generatedBy: record.generatedBy,\n oldBlob: entry.oldBlob === NULL_SHA ? null : entry.oldBlob,\n newBlob: entry.newBlob === NULL_SHA ? null : entry.newBlob,\n pathAtCommit: entry.newPath,\n otherParents: record.parents.slice(1),\n otherParentBlobs: [],\n });\n if (entry.oldPath !== entry.newPath) tracked.set(rel, entry.oldPath);\n }\n }\n return histories;\n}\n\n// ---------------------------------------------------------------------------\n// Blobs\n\nfunction neededBlobs(histories: Map<string, FileHistory[]>): Set<string> {\n const shas = new Set<string>();\n for (const history of histories.values()) {\n for (const h of history) {\n if (h.oldBlob !== null) shas.add(h.oldBlob);\n if (h.newBlob !== null) shas.add(h.newBlob);\n for (const b of h.otherParentBlobs) if (b !== null) shas.add(b);\n }\n }\n return shas;\n}\n\n/**\n * Fill each merge's `otherParentBlobs`: the document's blob at every parent\n * after the first, by `<parent>:<path>`. One `git cat-file --batch-check`\n * per root, which answers one line per spec in input order:\n * `<sha> <type> <size>`, or `<spec> missing` where the parent lacks the path.\n */\nasync function readOtherParentBlobs(\n run: GitRun,\n histories: ReadonlyMap<string, FileHistory[]>,\n): Promise<void> {\n const merges: FileHistory[] = [];\n const specs: string[] = [];\n for (const history of histories.values()) {\n for (const h of history) {\n if (h.otherParents.length === 0) continue;\n merges.push(h);\n for (const parent of h.otherParents) specs.push(`${parent}:${h.pathAtCommit}`);\n }\n }\n if (specs.length === 0) return;\n const out = await run([\"cat-file\", \"--batch-check\"], `${specs.join(\"\\n\")}\\n`);\n if (out.tooLarge) throw new HistoryTooLarge();\n if (out.code !== 0) throw new BlobsUnreadable(`exit ${String(out.code)}`);\n const lines = text(out).split(\"\\n\");\n let i = 0;\n for (const h of merges) {\n h.otherParentBlobs = h.otherParents.map(() => blobOfCheckLine(lines[i++]));\n }\n}\n\n/** The blob sha a `--batch-check` line names, or null for anything else. */\nfunction blobOfCheckLine(line: string | undefined): string | null {\n const [sha, kind] = (line ?? \"\").split(\" \");\n if (sha === undefined || kind !== \"blob\" || !/^[0-9a-f]{40,64}$/.test(sha)) return null;\n return sha;\n}\n\n/**\n * One `git cat-file --batch` per root, one sha per line on stdin. Output is\n * `<sha> blob <size>\\n<bytes>\\n` per object, correlated by the header's sha\n * rather than by order; a `<sha> missing` line yields nothing.\n */\nasync function fetchBlobs(\n run: GitRun,\n shas: Set<string>,\n): Promise<Map<string, string>> {\n const blobs = new Map<string, string>();\n if (shas.size === 0) return blobs;\n const out = await run([\"cat-file\", \"--batch\"], `${[...shas].join(\"\\n\")}\\n`);\n if (out.tooLarge) throw new HistoryTooLarge();\n if (out.code !== 0) throw new BlobsUnreadable(`exit ${String(out.code)}`);\n const buf = out.raw;\n let cursor = 0;\n while (cursor < buf.length) {\n const nl = buf.indexOf(0x0a, cursor);\n if (nl === -1) break;\n const header = buf.toString(\"utf8\", cursor, nl).split(\" \");\n cursor = nl + 1;\n const sha = header[0];\n const kind = header[1];\n const size = Number(header[2]);\n if (sha === undefined || kind !== \"blob\" || !Number.isFinite(size)) {\n continue;\n }\n blobs.set(sha, buf.toString(\"utf8\", cursor, cursor + size));\n cursor += size + 1; // the trailing newline after the object\n }\n return blobs;\n}\n\n// ---------------------------------------------------------------------------\n// The judge\n\nconst git = (value: unknown, evidence: string): DerivedValue => ({\n value,\n source: \"git\",\n evidence,\n});\n\n/**\n * The commits decision 2 reads a document's facts from: its oldest, for\n * `created`, and its newest body change, for `last-updated`.\n * `bodyChanging` is oldest first, so authors read in order of first appearance.\n */\ninterface FactCommits {\n bodyChanging: FileHistory[];\n oldest: FileHistory | undefined;\n newestBody: FileHistory | undefined;\n}\n\nfunction factCommits(\n input: DeriveInput,\n history: readonly FileHistory[],\n blobs: ReadonlyMap<string, string>,\n): FactCommits {\n const fenced = input.extracted.fenced;\n const blobBody = (sha: string | null): string | null =>\n sha === null ? null : bodyOf(blobs.get(sha) ?? \"\", fenced);\n const bodyChanging = [...history]\n .reverse()\n .filter((h) => {\n const body = blobBody(h.newBlob);\n if (sameBody(body, blobBody(h.oldBlob))) return false;\n // A merge that took the body whole from another parent did not write it.\n return !h.otherParentBlobs.some((b) => b !== null && sameBody(body, blobBody(b)));\n });\n return {\n bodyChanging,\n oldest: history[history.length - 1],\n newestBody: bodyChanging[bodyChanging.length - 1],\n };\n}\n\n/**\n * The value a manifest held for one dated field of a page (proposal 0069,\n * rule 1), at a commit (`sha`) or at its first parent (`sha^`). Undefined\n * when no manifest owns the field, or the manifest held no value there.\n */\ntype ManifestStamp = (field: StampedDateField, rev: string) => unknown;\n\n/**\n * Read, per page, the stamps the manifests that own its dated fields held at\n * the fact commits: the oldest commit for `created`, and the newest body\n * change and its parent for `last-updated`. One `git cat-file --batch` by\n * `<rev>:<path>` for the whole root, as provenance reads its manifest.\n */\nasync function stampsInManifests(\n run: GitRun,\n root: string,\n bucket: readonly RootEntry[],\n histories: ReadonlyMap<string, FileHistory[]>,\n blobs: ReadonlyMap<string, string>,\n parse: ParseYaml,\n): Promise<Map<string, ManifestStamp>> {\n interface Read {\n label: string;\n field: StampedDateField;\n rev: string;\n spec: string;\n key: string;\n join: string;\n }\n const reads: Read[] = [];\n for (const entry of bucket) {\n const refs = entry.input.stampManifests;\n if (refs === undefined) continue;\n const { oldest, newestBody } = factCommits(entry.input, histories.get(entry.rel) ?? [], blobs);\n for (const field of STAMPED_DATE_FIELDS) {\n const ref = refs[field];\n const at = field === \"created\" ? oldest : newestBody;\n if (ref === undefined || at === undefined) continue;\n const rel = insideRoot(root, ref.absPath);\n if (rel === undefined) continue;\n const key = ref.join === \"path\" ? entryAt(ref.entry, entry.rel, at.pathAtCommit) : ref.entry;\n const revs = field === \"created\" ? [at.sha] : [at.sha, `${at.sha}^`];\n for (const rev of revs) {\n reads.push({ label: entry.input.label, field, rev, spec: `${rev}:${rel}`, key, join: ref.join });\n }\n }\n }\n const out = new Map<string, ManifestStamp>();\n if (reads.length === 0) return out;\n const fetched = await fetchSpecs(run, [...new Set(reads.map((r) => r.spec))]);\n const values = new Map<string, unknown>();\n const keyOf = (label: string, field: string, rev: string): string => `${label}\\0${field}\\0${rev}`;\n for (const r of reads) {\n values.set(keyOf(r.label, r.field, r.rev), manifestValue(fetched.get(r.spec), r.key, r.join, r.field, parse));\n }\n for (const label of new Set(reads.map((r) => r.label))) {\n out.set(label, (field, rev) => values.get(keyOf(label, field, rev)));\n }\n return out;\n}\n\nfunction judge(\n input: DeriveInput,\n root: string,\n history: readonly FileHistory[],\n blobs: Map<string, string>,\n now: () => Date,\n machines: readonly string[],\n manifestStamp?: ManifestStamp,\n): GitFacts {\n const fenced = input.extracted.fenced;\n const extractor = extractorFor(input);\n const blobBody = (sha: string | null): string | null =>\n sha === null ? null : bodyOf(blobs.get(sha) ?? \"\", fenced);\n const stampsOf = (sha: string | null): Record<string, unknown> => {\n if (sha === null) return {};\n const content = blobs.get(sha);\n return content === undefined ? {} : extractStamps(extractor, content, input.absPath);\n };\n /**\n * The stamp a commit carries for a dated field (0069 rule 1): the owning\n * manifest's value at the commit, or else the page's. `parent` reads the\n * state before the commit, which tells a changed stamp from a kept one.\n */\n const stampAt = (field: StampedDateField, h: FileHistory, parent: boolean): unknown => {\n const kept = manifestStamp?.(field, parent ? `${h.sha}^` : h.sha);\n if (kept !== undefined && kept !== null) return kept;\n return stampsOf(parent ? h.oldBlob : h.newBlob)[field];\n };\n\n const { bodyChanging, oldest, newestBody } = factCommits(input, history, blobs);\n const head = history[0];\n const headBlob = head === undefined ? null : head.newBlob;\n\n const created = oldest === undefined ? null : createdOf(oldest, stampAt(\"created\", oldest, false));\n\n const workingChanged = !sameBody(\n bodyOf(input.content, fenced),\n headBlob === null ? null : blobBody(headBlob),\n );\n\n let lastUpdated: DerivedValue | null;\n let lastBodyCommit: string | null;\n if (workingChanged) {\n lastBodyCommit = null;\n const working = input.extracted.data[\"last-updated\"];\n const committed = stampsOf(headBlob)[\"last-updated\"];\n lastUpdated =\n working !== undefined && working !== null && !sameValue(working, committed)\n ? git(working, \"stamped in working tree\")\n : git(utcDate(now()), \"uncommitted body change\");\n } else if (newestBody === undefined) {\n lastBodyCommit = null;\n lastUpdated = null;\n } else {\n lastBodyCommit = newestBody.sha;\n lastUpdated = lastUpdatedOf(\n newestBody,\n stampAt(\"last-updated\", newestBody, false),\n stampAt(\"last-updated\", newestBody, true),\n );\n }\n\n const authors = bodyChanging.length === 0 ? null : authorsOf(bodyChanging, machines);\n\n let reviewedBy: DerivedValue | null = null;\n let lastReviewed: DerivedValue | null = null;\n if (!workingChanged && newestBody !== undefined && newestBody.reviewedBy.length > 0) {\n const evidence = `Reviewed-by trailer in ${short(newestBody.sha)}`;\n reviewedBy = git(newestBody.reviewedBy.map(nameOf), evidence);\n lastReviewed = git(datePart(newestBody.authorDate), evidence);\n }\n\n return {\n created,\n \"last-updated\": lastUpdated,\n authors,\n \"reviewed-by\": reviewedBy,\n \"last-reviewed\": lastReviewed,\n provenance: null,\n lastBodyCommit,\n root,\n };\n}\n\nfunction createdOf(oldest: FileHistory, stamp: unknown): DerivedValue {\n if (stamp !== undefined && stamp !== null) {\n return git(stamp, `stamped in ${short(oldest.sha)}`);\n }\n const date = datePart(oldest.authorDate);\n return git(date, `added in ${short(oldest.sha)} (${date})`);\n}\n\n/**\n * `last-updated` from the newest body change (decision 2). A stamp counts\n * only when the commit changed it, on the page or in the manifest that owns\n * the field: a stamp the edit kept was written for an earlier change, so the\n * commit's own date stands.\n */\nfunction lastUpdatedOf(commit: FileHistory, stamp: unknown, before: unknown): DerivedValue {\n if (stamp !== undefined && stamp !== null && !sameValue(stamp, before)) {\n return git(stamp, `stamped in ${short(commit.sha)}`);\n }\n const date = datePart(commit.authorDate);\n return git(date, `body changed in ${short(commit.sha)} (${date})`);\n}\n\n/**\n * Distinct people behind the body-changing commits, oldest first, each\n * commit's author ahead of its co-authors, deduplicated by lowercase email\n * (by lowercase name when a co-author trailer carries none). An identity\n * whose name or email matches `derive.machines` is a machine and is left\n * out (proposal 0046); the default, `*[bot]`, is a name ending `[bot]`.\n */\nfunction authorsOf(bodyChanging: readonly FileHistory[], machines: readonly string[]): DerivedValue {\n const seen = new Set<string>();\n const names: string[] = [];\n const add = (name: string, email: string | null): void => {\n if (name === \"\") return;\n const identity = email === null || email === \"\" ? name : `${name} <${email}>`;\n if (machineIdentity(identity, machines) !== undefined) return;\n const key = email === null || email === \"\" ? `name:${name.toLowerCase()}` : email.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n names.push(name);\n };\n for (const h of bodyChanging) {\n add(h.authorName, h.authorEmail);\n for (const co of h.coAuthors) add(nameOf(co), emailOf(co));\n }\n const n = bodyChanging.length;\n return git(names, `${n} body-changing ${n === 1 ? \"commit\" : \"commits\"}`);\n}\n\n// ---------------------------------------------------------------------------\n// provenance (proposal 0046)\n\n/**\n * Whether a page's metadata is a leading fenced block for provenance's\n * purposes: extracted from one, or a format whose metadata can only ever be\n * one (a Markdown or MDX page with no block yet gets a fenced one when it is\n * stamped). Everywhere else the metadata is part of the body it would pin,\n * so the page cannot carry the stamp itself (stress test 8).\n */\nexport function provenanceFenced(extracted: Pick<ExtractedMetadata, \"fenced\" | \"format\">): boolean {\n return extracted.fenced === true || extracted.format === \"markdown\" || extracted.format === \"mdx\";\n}\n\n/**\n * The sha an out-of-range uncommitted line is given under a ranged\n * attribution: a commit with no trailers and no blob, so it resolves to no\n * evidence. With a range, `--generated-by` names those lines only; the\n * other uncommitted lines are not its to attribute.\n */\nconst OUTSIDE_RANGE = \"outside-the-attributed-range\";\n\n/** The suffix a ranged attribution keys a committed line's commit under; the sha stays its prefix. */\nconst ATTRIBUTED = \":attributed\";\n\ninterface ProvenanceRun {\n machines: readonly string[];\n generatedBy?: string;\n}\n\n/**\n * One page's provenance from its blame and what each blamed commit offers\n * (its trailers and the page or manifest blob at it): the evidence rules.\n */\nfunction provenanceFor(\n entry: RootEntry,\n blame: BlameLine[],\n commits: Map<string, CommitEvidence>,\n opts: ProvenanceRun,\n): { value: DerivedValue | null; derivation: ProvenanceDerivation } {\n const { input } = entry;\n const fenced = provenanceFenced(input.extracted);\n const base = { content: input.content, commits, machines: opts.machines, fenced };\n\n let derivation: ProvenanceDerivation;\n const attribution = input.attribution;\n if (attribution !== undefined) {\n // Refused in 0046's words when a range runs past the end, reaches into\n // the frontmatter, or evidence names another machine for any of its\n // non-blank lines. Each range is the one attributeRange writes, trimmed\n // of blank edge lines (0071), in file lines: a blank line outside it is\n // not the attribution's, and one of only blank lines attributes nothing.\n const page = readProvenancePage(input.content, { fenced });\n const { bodyLine } = page;\n const ranges = attribution.targets.flatMap((target) => {\n const entry = attributeRange({ ...base, blame, target, generatedBy: attribution.generatedBy, page });\n const span = entry === undefined ? undefined : parseLines(entry.lines);\n return span === undefined ? [] : [toFileLines(span, bodyLine)];\n });\n const inRange = (line: BlameLine): boolean =>\n ranges.some((range) => line.finalLine >= range.start && line.finalLine <= range.end);\n // The attribution is evidence of its own, and nothing contradicts it (the\n // refusal above made sure). A committed line in the range is read as its\n // commit naming the machine, under a key that keeps the commit's sha for\n // the evidence text and leaves the commit's other lines as they were; an\n // uncommitted one is rule 1's. An uncommitted line outside the range has\n // no evidence: the range is what --generated-by names.\n const attributed = new Map(commits);\n const trailers = { generatedBy: [attribution.generatedBy], coAuthoredBy: [] };\n attributed.set(OUTSIDE_RANGE, { sha: OUTSIDE_RANGE, trailers: { generatedBy: [], coAuthoredBy: [] } });\n const rekeyed = blame.map((line): BlameLine => {\n if (inRange(line)) {\n if (line.uncommitted) return line;\n const sha = `${line.sha}${ATTRIBUTED}`;\n attributed.set(sha, { sha, trailers });\n return { ...line, sha };\n }\n return line.uncommitted ? { ...line, sha: OUTSIDE_RANGE, uncommitted: false } : line;\n });\n derivation = deriveProvenance({\n ...base,\n commits: attributed,\n generatedBy: attribution.generatedBy,\n blame: rekeyed,\n });\n } else {\n derivation = deriveProvenance({\n ...base,\n blame,\n ...(opts.generatedBy !== undefined ? { generatedBy: opts.generatedBy } : {}),\n });\n }\n\n const entries: ProvenanceEntry[] = derivation.derived.map((d) => d.entry);\n return {\n value: entries.length === 0 ? null : git(entries, provenanceEvidence(derivation)),\n derivation,\n };\n}\n\n/**\n * `blame 9b0e2c1`, `blame 9b0e2c1, 2 commits`, or `uncommitted`: the commits\n * behind the machine-attributed lines, the first in line order named, and\n * `uncommitted` when rule 1 answered for any of them.\n */\nfunction provenanceEvidence(derivation: ProvenanceDerivation): string {\n const shas: string[] = [];\n let uncommitted = false;\n for (const range of derivation.derived) {\n for (let n = range.span.start; n <= range.span.end; n++) {\n const evidence = derivation.evidenceByLine.get(n);\n if (evidence?.machine === undefined) continue;\n if (evidence.rule === 1) uncommitted = true;\n else if (!shas.includes(evidence.sha)) shas.push(evidence.sha);\n }\n }\n const first = shas[0];\n if (first === undefined) return \"uncommitted\";\n const parts = [`blame ${short(first)}`];\n if (shas.length > 1) parts.push(`${String(shas.length)} commits`);\n if (uncommitted) parts.push(\"uncommitted\");\n return parts.join(\", \");\n}\n\n/**\n * `git blame --line-porcelain` over the working file. A path HEAD does not\n * have has nothing to blame, so every line is uncommitted: that covers an\n * untracked file, a repository with no commits, and a file deleted in history\n * and recreated, which has history but no blob in HEAD. Blame failing on a\n * path HEAD has is the root's failure, and git's stderr says why.\n *\n * `--no-ignore-revs-file` because a `blame.ignoreRevsFile` in someone's\n * global config would otherwise move lines onto other commits (or, naming a\n * file the repository lacks, fail blame outright), and attribution must not\n * depend on the machine it runs on. An empty `-c blame.ignoreRevsFile=` does\n * not clear the setting; the flag does.\n */\nasync function blameOf(run: GitRun, rel: string, content: string): Promise<BlameLine[]> {\n const out = await run([\n \"-c\",\n \"core.quotePath=false\",\n \"blame\",\n \"--no-ignore-revs-file\",\n \"--line-porcelain\",\n \"--\",\n rel,\n ]);\n if (out.tooLarge) throw new HistoryTooLarge();\n if (out.code !== 0) {\n // Asked only once blame has failed, so a page that blames cleanly pays nothing.\n const inHead = await run([\"cat-file\", \"-e\", `HEAD:${rel}`]);\n if (inHead.code !== 0) {\n return splitLines(content).map((line, i) => ({\n sha: ZERO_SHA,\n origLine: i + 1,\n finalLine: i + 1,\n author: \"Not Committed Yet\",\n authorMail: \"not.committed.yet\",\n filename: rel,\n boundary: false,\n uncommitted: true,\n content: line,\n }));\n }\n throw new BlameUnreadable(rel, out.stderr.trim());\n }\n return parseLinePorcelain(text(out));\n}\n\n/** One page's blame, with the history already read for it. */\ninterface BlamedPage {\n entry: RootEntry;\n blame: BlameLine[];\n history: readonly FileHistory[];\n}\n\n/**\n * What each blamed commit offers each page: its trailers, from the page's\n * history or else `git log --no-walk` for a commit it lacks, and the page's\n * text at that commit, from the blobs already read or else `git cat-file\n * --batch` by `<sha>:<path>`. When a manifest holds the record, the stamp is\n * read from the manifest's blob at the same commit, under the page's entry as\n * it was keyed then: for a `path` join, the page's path at that commit, so a\n * stamp written before a rename is still found under the old key. Every page\n * of the root is read in one log and one batch, not one of each per page; the\n * answer is one map per page, in input order.\n */\nasync function commitEvidence(\n run: GitRun,\n root: string,\n pages: readonly BlamedPage[],\n blobs: ReadonlyMap<string, string>,\n parse: ParseYaml,\n): Promise<Map<string, CommitEvidence>[]> {\n const plans = pages.map(({ entry, blame, history }) => {\n const pathAt = new Map<string, string>();\n for (const line of blame) {\n if (!line.uncommitted && !pathAt.has(line.sha)) pathAt.set(line.sha, unquotePath(line.filename));\n }\n const trailers = new Map<string, CommitEvidence[\"trailers\"]>();\n const pageBlob = new Map<string, string>();\n for (const h of history) {\n trailers.set(h.sha, { generatedBy: h.generatedBy, coAuthoredBy: h.coAuthors });\n const blob = h.newBlob === null ? undefined : blobs.get(h.newBlob);\n if (blob !== undefined) pageBlob.set(h.sha, blob);\n }\n const manifest = entry.input.provenanceManifest;\n const manifestRel = manifest === undefined ? undefined : insideRoot(root, manifest.absPath);\n return { entry, pathAt, trailers, pageBlob, manifest, manifestRel };\n });\n\n const unlogged = new Set<string>();\n const specs = new Set<string>();\n for (const { pathAt, trailers, pageBlob, manifestRel } of plans) {\n for (const [sha, path] of pathAt) {\n if (!trailers.has(sha)) unlogged.add(sha);\n if (!pageBlob.has(sha)) specs.add(`${sha}:${path}`);\n if (manifestRel !== undefined) specs.add(`${sha}:${manifestRel}`);\n }\n }\n\n const logged = new Map<string, CommitEvidence[\"trailers\"]>();\n if (unlogged.size > 0) {\n // On stdin, so a whole root's shas cannot outgrow the command line.\n const out = await run([\"log\", \"--no-walk=unsorted\", \"--stdin\", RECORD_FORMAT], `${[...unlogged].join(\"\\n\")}\\n`);\n if (out.tooLarge) throw new HistoryTooLarge();\n if (out.code !== 0) throw new BlobsUnreadable(`git log exit ${String(out.code)}`);\n for (const record of parseLog(text(out))) {\n logged.set(record.sha, { generatedBy: record.generatedBy, coAuthoredBy: record.coAuthors });\n }\n }\n const fetched = await fetchSpecs(run, [...specs]);\n\n return plans.map(({ entry, pathAt, trailers, pageBlob, manifest, manifestRel }) => {\n const commits = new Map<string, CommitEvidence>();\n for (const [sha, path] of pathAt) {\n const blob = pageBlob.get(sha) ?? fetched.get(`${sha}:${path}`);\n commits.set(sha, {\n sha,\n trailers: trailers.get(sha) ?? logged.get(sha) ?? { generatedBy: [], coAuthoredBy: [] },\n ...(blob !== undefined ? { blob } : {}),\n ...(manifest !== undefined\n ? {\n stamp:\n manifestRel === undefined\n ? []\n : manifestStamp(\n fetched.get(`${sha}:${manifestRel}`),\n manifest.join === \"path\" ? entryAt(manifest.entry, entry.rel, path) : manifest.entry,\n manifest.join,\n parse,\n ),\n }\n : {}),\n });\n }\n return commits;\n });\n}\n\n/** A path under the root as git names it, or undefined outside the root. */\nfunction insideRoot(root: string, abs: string): string | undefined {\n const rel = relative(root, abs);\n if (rel === \"\" || rel.startsWith(\"..\") || isAbsolute(rel)) return undefined;\n return rel.split(sep).join(\"/\");\n}\n\n/**\n * A `path` join's key for the page as it was named at one commit. `entry` is\n * the current path relative to the config directory and `rel` the current\n * path relative to the root, so the path at the commit (root-relative, as\n * blame names it) is re-expressed from the current file's directory and\n * joined onto the entry's. That holds for an entry that climbs out of the\n * config directory with `..`, and needs no config directory of its own.\n */\nfunction entryAt(entry: string, rel: string, relAtCommit: string): string {\n if (relAtCommit === rel) return entry;\n const fromHere = posix.relative(posix.dirname(rel), relAtCommit);\n return posix.join(posix.dirname(entry), fromHere);\n}\n\n/**\n * The `provenance` entries a manifest's text holds for one page, under `key`\n * (joined on `join`). A manifest that does not parse, or has no entry for the\n * page, holds none.\n */\nfunction manifestStamp(\n text: string | undefined,\n key: string,\n join: ManifestRef[\"join\"],\n parse: ParseYaml,\n): ProvenanceEntry[] {\n return provenanceEntries(manifestValue(text, key, join, PROVENANCE_FIELD, parse));\n}\n\n/** Manifest text to its parsed data, or undefined when it does not parse. */\ntype ParseYaml = (text: string) => unknown;\n\n/**\n * A `ParseYaml` that parses each distinct text once. A manifest's blob is\n * read for every page it holds and at every commit a page's blame names, and\n * it is mostly the same bytes each time. One per run, so nothing outlives it.\n */\nexport function yamlOnce(): ParseYaml {\n const parsed = new Map<string, unknown>();\n return (text) => {\n if (parsed.has(text)) return parsed.get(text);\n let data: unknown;\n try {\n data = parseYaml(text);\n } catch {\n data = undefined;\n }\n parsed.set(text, data);\n return data;\n };\n}\n\n/**\n * One field's value in a manifest's text for one page, under `key` (joined\n * on `join`). Undefined when the manifest does not parse, has no entry for\n * the page, or the entry has no such field.\n */\nfunction manifestValue(\n text: string | undefined,\n key: string,\n join: ManifestRef[\"join\"],\n field: string,\n parse: ParseYaml,\n): unknown {\n if (text === undefined) return undefined;\n const data = parse(text);\n if (!isRecord(data)) return undefined;\n for (const [candidate, value] of Object.entries(data)) {\n const same =\n join === \"path\" ? posix.normalize(candidate) === posix.normalize(key) : candidate === key;\n if (same && isRecord(value)) return value[field];\n }\n return undefined;\n}\n\nfunction isRecord(x: unknown): x is Record<string, unknown> {\n return typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\n/**\n * `git cat-file --batch` by `<rev>:<path>`, keyed by the spec. The output\n * header names the object, not the spec, so it is read in input order; a\n * spec that names nothing answers `<spec> missing` and yields nothing. An\n * answer past the read cap is asked for again in halves, since one batch now\n * serves a whole root; only one object past the cap is too large.\n */\nasync function fetchSpecs(run: GitRun, specs: readonly string[]): Promise<Map<string, string>> {\n const found = new Map<string, string>();\n if (specs.length === 0) return found;\n const out = await run([\"cat-file\", \"--batch\"], `${specs.join(\"\\n\")}\\n`);\n if (out.tooLarge && specs.length > 1) {\n const half = Math.ceil(specs.length / 2);\n const first = await fetchSpecs(run, specs.slice(0, half));\n const rest = await fetchSpecs(run, specs.slice(half));\n return new Map([...first, ...rest]);\n }\n if (out.tooLarge) throw new HistoryTooLarge();\n if (out.code !== 0) throw new BlobsUnreadable(`exit ${String(out.code)}`);\n for (const [spec, content] of parseSpecBatch(out.raw, specs)) found.set(spec, content);\n return found;\n}\n\n/**\n * The objects a `git cat-file --batch` answer holds for `specs`, in input\n * order. A header that cannot be read, or output that ends before every spec\n * is answered, leaves no way to find the next object, so the answer is\n * refused rather than cut short: a cut-short answer would read the rest as\n * stamps that are not there, and report them stale.\n */\nexport function parseSpecBatch(buf: Buffer, specs: readonly string[]): Map<string, string> {\n const found = new Map<string, string>();\n let cursor = 0;\n for (const spec of specs) {\n const nl = buf.indexOf(0x0a, cursor);\n if (nl === -1) throw new BlobsUnreadable(`the answer ends before ${spec}`);\n const header = buf.toString(\"utf8\", cursor, nl);\n cursor = nl + 1;\n if (header.endsWith(\" missing\") || header.endsWith(\" ambiguous\")) continue;\n const parts = header.split(\" \");\n const size = Number(parts[2]);\n if (parts.length !== 3 || !Number.isInteger(size) || size < 0) {\n throw new BlobsUnreadable(`unreadable header for ${spec}: ${header}`);\n }\n if (parts[1] === \"blob\") found.set(spec, buf.toString(\"utf8\", cursor, cursor + size));\n cursor += size + 1;\n }\n return found;\n}\n\n// ---------------------------------------------------------------------------\n// Small helpers\n\nfunction extractorFor(input: DeriveInput): MetadataExtractor | undefined {\n return (\n extractorByName(input.extracted.format) ??\n extractorForExtension(extname(input.absPath))\n );\n}\n\n/** The stamps a blob carries; a blob that fails to parse carries none. */\nfunction extractStamps(\n extractor: MetadataExtractor | undefined,\n content: string,\n filePath: string,\n): Record<string, unknown> {\n if (!extractor) return {};\n try {\n return extractor.extract(content, filePath).data;\n } catch {\n return {};\n }\n}\n\n/**\n * Bodies compare with CRLF folded to LF: `core.autocrlf` rewrites line\n * endings between the working tree and the index, and that is not an edit.\n * An absent blob (a file being added, or one with no history) matches only\n * another absent blob.\n */\nfunction sameBody(a: string | null, b: string | null): boolean {\n if (a === null || b === null) return a === b;\n return a.replace(/\\r\\n/g, \"\\n\") === b.replace(/\\r\\n/g, \"\\n\");\n}\n\nfunction sameValue(a: unknown, b: unknown): boolean {\n return toJsonText(a) === toJsonText(b);\n}\n\nconst short = (sha: string): string => sha.slice(0, 7);\n\n/**\n * The UTC `YYYY-MM-DD` of a `%aI` string (proposal 0072). The author's own\n * offset would date one instant differently on two machines, so a page\n * stamped on a branch read stale on main once a squash put another commit's\n * offset in its place.\n */\nconst datePart = (iso: string): string => {\n const d = new Date(iso);\n // A malformed record parses to an empty author date; keep it empty rather\n // than throw, as slicing the string did.\n return Number.isNaN(d.getTime()) ? \"\" : utcDate(d);\n};\n\n/** Today, or any instant, as a UTC day: the same answer on every machine. */\nfunction utcDate(d: Date): string {\n return d.toISOString().slice(0, 10);\n}\n\n/** `Name <email>` → `Name`; a bare name is returned trimmed. */\nfunction nameOf(trailer: string): string {\n const lt = trailer.lastIndexOf(\"<\");\n return (lt === -1 ? trailer : trailer.slice(0, lt)).trim();\n}\n\nfunction emailOf(trailer: string): string | null {\n const m = /<([^>]*)>\\s*$/.exec(trailer);\n return m?.[1]?.trim() ?? null;\n}\n\n// ---------------------------------------------------------------------------\n// Process plumbing\n\ninterface GitOutput {\n /** Exit code; null when git was killed by a signal or never started. */\n code: number | null;\n /**\n * The bytes of stdout, undecoded: `cat-file` sizes are byte counts, and\n * the log is decoded only where it is read, through `text()`.\n */\n raw: Buffer;\n /** True when `git` itself could not be started (not on PATH). */\n missing: boolean;\n /** True when stdout passed the byte cap; `raw` is then empty. */\n tooLarge: boolean;\n /** The start of stderr, decoded, for a failure message; `MAX_STDERR_BYTES` at most. */\n stderr: string;\n}\n\n/** How much of a git process's stderr is kept: enough for its `fatal:` line. */\nconst MAX_STDERR_BYTES = 16 * 1024;\n\n/** One git command in a fixed root, with the run's byte cap bound in. */\ntype GitRun = (args: string[], stdin?: string) => Promise<GitOutput>;\n\n/**\n * How many pages derive reads from git at once. Past eight, a measured run of\n * 239 blames gained little (2.1s at 8, 1.7s at 24, 12s one at a time).\n */\nconst GIT_CONCURRENCY = Math.min(8, availableParallelism());\n\n/**\n * Decode stdout as UTF-8. The cap keeps the byte count under V8's string\n * limit, so a decode that still throws is treated the same way rather than\n * escaping as a crash.\n */\nfunction text(out: GitOutput): string {\n try {\n return out.raw.toString(\"utf8\");\n } catch {\n throw new HistoryTooLarge();\n }\n}\n\n/**\n * One git process from `cwd`, modelled on `checkIgnore` in gitignore.ts.\n * stdout is collected whole and capped at `maxBytes`: past the cap the\n * child is killed and the result says `tooLarge` instead of carrying the\n * bytes. Anything thrown while assembling the result rejects the promise\n * rather than escaping the 'close' handler as an uncaught exception.\n */\nfunction runGit(\n args: string[],\n cwd: string,\n stdin: string | undefined,\n maxBytes: number,\n): Promise<GitOutput> {\n return new Promise((settle, reject) => {\n let done = false;\n const finish = (out: GitOutput): void => {\n if (done) return;\n done = true;\n settle(out);\n };\n const fail = (err: unknown): void => {\n if (done) return;\n done = true;\n reject(err instanceof Error ? err : new Error(String(err)));\n };\n const failed = (missing: boolean): GitOutput => ({\n code: null,\n raw: Buffer.alloc(0),\n missing,\n tooLarge: false,\n stderr: \"\",\n });\n\n let child: ChildProcessWithoutNullStreams;\n try {\n child = spawn(\"git\", args, { cwd, windowsHide: true });\n } catch {\n finish(failed(true));\n return;\n }\n\n let chunks: Buffer[] = [];\n let total = 0;\n let tooLarge = false;\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (tooLarge) return;\n total += chunk.length;\n if (total > maxBytes) {\n tooLarge = true;\n chunks = [];\n child.kill();\n return;\n }\n chunks.push(chunk);\n });\n // Drain stderr so a chatty git cannot fill the pipe and stall, keeping\n // its start for the message a failure reports.\n const errChunks: Buffer[] = [];\n let errTotal = 0;\n child.stderr.on(\"data\", (chunk: Buffer) => {\n if (errTotal >= MAX_STDERR_BYTES) return;\n const kept = chunk.subarray(0, MAX_STDERR_BYTES - errTotal);\n errTotal += kept.length;\n errChunks.push(kept);\n });\n // No binary on PATH lands here rather than throwing from spawn().\n child.on(\"error\", (err: NodeJS.ErrnoException) => {\n finish(failed(err.code === \"ENOENT\"));\n });\n // A dead child makes the pipe write fail; 'error'/'close' report that.\n child.stdin.on(\"error\", () => {});\n child.on(\"close\", (code) => {\n try {\n const raw = tooLarge ? Buffer.alloc(0) : Buffer.concat(chunks);\n const stderr = Buffer.concat(errChunks).toString(\"utf8\");\n finish({ code, raw, missing: false, tooLarge, stderr });\n } catch (err) {\n fail(err);\n }\n });\n\n if (stdin === undefined) child.stdin.end();\n else child.stdin.end(stdin);\n });\n}\n","/** Bounded worker pool that preserves input order in its output. */\nexport async function mapConcurrent<T, R>(\n items: readonly T[],\n limit: number,\n fn: (item: T) => Promise<R>,\n): Promise<R[]> {\n const out = new Array<R>(items.length);\n let next = 0;\n const workers = Array.from(\n { length: Math.max(1, Math.min(limit, items.length)) },\n async () => {\n for (;;) {\n const i = next++;\n const item = items[i];\n if (i >= items.length || item === undefined) return;\n out[i] = await fn(item);\n }\n },\n );\n await Promise.all(workers);\n return out;\n}\n","/**\n * The `derived` table (proposal 0040): what the evidence says each derivable\n * field should be, one row per file, as a read-only SQL view beside `docs`.\n *\n * `query` builds it when a statement names it, and a corpus check that names\n * it gets the same view — this module is what keeps the two from drifting.\n * It is a view over a backing table rather than a table, so that SQLite's own\n * `cannot modify derived because it is a view` refuses a write before any\n * effect gate has to: the value it holds is not stored anywhere, and the only\n * way to change it is to change the evidence. Both objects are transient: a\n * `--db` export drops them before the handle closes, so a frozen derived\n * value never outlives the run that computed it.\n *\n * The columns are the run's: the six built-in fields, then one per key of\n * `derive.commands` (proposal 0042), so a command-derived field is read\n * exactly as a built-in one is.\n */\nimport type { DatabaseSync } from \"node:sqlite\";\nimport type { DocmetaConfig } from \"../config.js\";\nimport { bindValue, quoteIdent, RESERVED } from \"../projection.js\";\nimport { commandsOf, machinesOf } from \"./config.js\";\nimport { assertSourcesAvailable, deriveMetadata } from \"./index.js\";\nimport {\n DERIVE_SOURCES,\n PROVENANCE_FIELD,\n derivableFields,\n type DerivableField,\n type DeriveCommand,\n type DerivedRecord,\n type DeriveInput,\n} from \"./types.js\";\n\n/** The view's name, and the backing table the rows actually sit in. */\nexport const DERIVED_VIEW = \"derived\";\nexport const DERIVED_ROWS = \"_derived_rows\";\n\n/** The third table: the effective value per field, over `docs` and the rows. */\nexport const RESOLVED_VIEW = \"resolved\";\n\n/** The two columns `resolved` adds past the fields: which side, and why. */\nconst ORIGIN_COLUMN = \"_origin\";\nconst SOURCES_COLUMN = \"_sources\";\n\n/** The view's columns, in order: the path, every derivable field, the evidence. */\nexport function derivedColumns(commands?: Readonly<Record<string, DeriveCommand>>): string[] {\n return [\"_path\", ...derivableFields(commands), SOURCES_COLUMN];\n}\n\n/**\n * Does the statement name the `derived` table? The search wants `derived`\n * where a table goes — after FROM, JOIN, UPDATE, INTO, TABLE or VIEW, bare\n * or double-quoted — so that the word inside a string literal, a comment or\n * a column alias does not spawn git for nothing. A spelling this misses\n * (`main.derived`, a CTE that shadows it) is caught by the engine's own\n * `no such table: derived`, which `query` rescues with a lazy build.\n */\nexport function mentionsDerived(sql: string): boolean {\n return /\\b(?:from|join|update|into|table|view)\\s+(?:\"derived\"|derived\\b)/i.test(sql);\n}\n\n/**\n * The derivable fields a statement can read, out of `fields` — the run's\n * own list, see `derivableFields`: every one of them when it selects `*`, or\n * reads `_sources` or `_origin` (the evidence and the origin map span them\n * all), otherwise the field names\n * it spells out, quoted or not. `provenance` is the exception to the first\n * half: it costs a blame per page, which proposal 0046 confines to runs that\n * ask for it, so only its name brings it in here (`derive.fields` is the\n * other way, which `deriveForTable` adds). `owner` is not `owners` and `created` is\n * not `recreated`, and the hyphen inside `last-updated` counts as part of\n * the name; a command key is matched as written, whatever it contains.\n * Over-triggering costs one source consulted for nothing; under-triggering\n * would leave a named column NULL, so a field that appears anywhere in the\n * text — a literal, a comment — is derived.\n */\nexport function fieldsForSql(sql: string, fields: readonly DerivableField[]): DerivableField[] {\n const named = (field: string): boolean =>\n new RegExp(`(?<![\\\\w-])${escapeRegExp(field)}(?![\\\\w-])`, \"i\").test(sql);\n if (sql.includes(\"*\") || /\\b_(?:sources|origin)\\b/i.test(sql)) {\n return fields.filter((field) => field !== PROVENANCE_FIELD || named(field));\n }\n return fields.filter(named);\n}\n\nfunction escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/**\n * Create the backing table, load one row per record, and expose it as the\n * `derived` view. `columns` is the run's list (`derivedColumns`), and the\n * values are placed by it, so the view and the rows agree by construction.\n * Values go through `bindValue`, so a list is JSON text exactly as it is in\n * `docs`; `_sources` is the JSON object `{field: {source, evidence}}` over\n * the non-null fields.\n */\nexport function createDerivedView(\n db: DatabaseSync,\n records: ReadonlyMap<string, DerivedRecord>,\n columns: readonly string[],\n): void {\n const quoted = columns.map(quoteIdent);\n db.exec(\n `CREATE TABLE ${DERIVED_ROWS} (${quoted\n .map((c, i) => (i === 0 ? `${c} TEXT PRIMARY KEY` : `${c} TEXT`))\n .join(\", \")})`,\n );\n const insert = db.prepare(\n `INSERT INTO ${DERIVED_ROWS} VALUES (${quoted.map(() => \"?\").join(\", \")})`,\n );\n const fields = columns.slice(1, -1);\n db.exec(\"BEGIN\");\n // Committed or rolled back, never left open: the caller may keep using the\n // handle after a failed insert, and every later statement would otherwise\n // run inside the half-built transaction.\n let committed = false;\n try {\n for (const [label, record] of records) {\n const sources: Record<string, { source: string; evidence: string }> = {};\n const values = fields.map((field) => {\n const derived = record.fields[field];\n if (derived == null) return null;\n sources[field] = { source: derived.source, evidence: derived.evidence };\n return bindValue(derived.value);\n });\n insert.run(label, ...values, JSON.stringify(sources));\n }\n db.exec(\"COMMIT\");\n committed = true;\n } finally {\n if (!committed) db.exec(\"ROLLBACK\");\n }\n db.exec(`CREATE VIEW ${DERIVED_VIEW} AS SELECT * FROM ${DERIVED_ROWS}`);\n}\n\n/**\n * Every column `resolved` carries, in order: `_path`, the `docs` data columns,\n * then any derivable field `docs` does not already have, then `_origin` and\n * `_sources`. A docs column that is also a derivable field appears once, in\n * the position `docs` gives it, so the field list only ever adds.\n *\n * The system columns are skipped: `_path` is already first, and `_format`,\n * `_present` and `_data` are facts about the document rather than values a\n * source could state. A frontmatter key spelled `_origin` or `_sources` is\n * skipped for the same reason a reserved one is — the column is taken.\n */\nexport function resolvedColumns(\n docsColumns: readonly string[],\n commands?: Readonly<Record<string, DeriveCommand>>,\n): string[] {\n const columns = [\"_path\"];\n const seen = new Set<string>([\"_path\", ORIGIN_COLUMN, SOURCES_COLUMN]);\n for (const column of docsColumns) {\n if (seen.has(column) || RESERVED.has(column)) continue;\n seen.add(column);\n columns.push(column);\n }\n for (const field of derivableFields(commands)) {\n if (seen.has(field)) continue;\n seen.add(field);\n columns.push(field);\n }\n columns.push(ORIGIN_COLUMN, SOURCES_COLUMN);\n return columns;\n}\n\n/**\n * Does the statement name the `resolved` table? The twin of `mentionsDerived`,\n * with the same shape and the same reason: `resolved` where a table goes, so\n * that a column alias or the word inside `unresolved` does not build a view —\n * and, more to the point, does not spawn git behind it.\n */\nexport function mentionsResolved(sql: string): boolean {\n return /\\b(?:from|join|update|into|table|view)\\s+(?:\"resolved\"|resolved\\b)/i.test(sql);\n}\n\n/** One field name as a SQLite JSON path step: `$.\"last-updated\"`. */\nfunction jsonPath(field: string): string {\n // JSON.stringify quotes and escapes exactly the way SQLite's path parser\n // reads a quoted label — `\\\"` for a quote, `\\\\` for a backslash — and the\n // way the label was written into `_data` in the first place.\n return `$.${JSON.stringify(field)}`;\n}\n\n/** Any string as a SQL string literal (doubling internal apostrophes). */\nfunction sqlString(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\n/**\n * Create the `resolved` view: one row per `docs` row, holding the effective\n * value of every field — what the document asserts when it carries the key,\n * what the evidence derived otherwise — plus `_origin` saying which of the two\n * answered, and the derived row's `_sources` unchanged. Call after\n * `createDocsTable` and `createDerivedView`.\n *\n * **Presence is decided by `_data`, never by NULL.** A docs column is NULL\n * both when the key is absent and when the document writes `key: null`, and\n * those are opposite answers: an explicit null is an assertion, and the\n * derived value must not overwrite it. So each field asks\n * `json_type(_data, '$.\"field\"') IS NOT NULL`, which is true for a JSON null\n * and false for an absent key.\n *\n * `_origin` is `json_patch('{}', json_object(…))` over a CASE per field that\n * yields `'asserted'`, `'derived'`, or NULL. `json_object` alone would keep\n * the NULL members — a field neither side has would read as present with a\n * null origin — and RFC 7396 merge-patch, which `json_patch` implements, is\n * exactly the \"a null member deletes the key\" rule that drops them. One patch\n * call does the whole object, so the shape stays flat however many fields the\n * run carries.\n *\n * The join is a LEFT JOIN, so a file the derive run has no row for keeps its\n * asserted values with an all-`asserted` `_origin` and a NULL `_sources`.\n *\n * Read-only by construction: SQLite refuses a write to a view with no\n * INSTEAD OF trigger, and there is none. The effective value is not stored\n * anywhere, so the only way to change it is to change the document or the\n * evidence.\n *\n * Call it after `createDocsTable` and `createDerivedView`. SQLite accepts a\n * view over a table that does not exist yet and fails only at the first read,\n * as `no such table: main._derived_rows`, far from the call that got the\n * order wrong.\n */\nexport function createResolvedView(\n db: DatabaseSync,\n docsColumns: readonly string[],\n commands?: Readonly<Record<string, DeriveCommand>>,\n): void {\n const columns = resolvedColumns(docsColumns, commands);\n const fields = columns.slice(1, -2);\n const inDocs = new Set(docsColumns);\n const inDerived = new Set(derivableFields(commands));\n\n const selects = [`d.${quoteIdent(\"_path\")} AS ${quoteIdent(\"_path\")}`];\n const origin: string[] = [];\n for (const field of fields) {\n const path = sqlString(jsonPath(field));\n const asserted = `json_type(d.${quoteIdent(\"_data\")}, ${path}) IS NOT NULL`;\n // A field with no docs column can only be asserted by an inconsistent\n // table, but `_data` answers for it either way and costs nothing here.\n const assertedValue = inDocs.has(field)\n ? `d.${quoteIdent(field)}`\n : `d.${quoteIdent(\"_data\")} ->> ${path}`;\n if (inDerived.has(field)) {\n const derivedValue = `r.${quoteIdent(field)}`;\n selects.push(\n `CASE WHEN ${asserted} THEN ${assertedValue} ELSE ${derivedValue} END AS ${quoteIdent(field)}`,\n );\n origin.push(\n `${sqlString(field)}, CASE WHEN ${asserted} THEN 'asserted' WHEN ${derivedValue} IS NOT NULL THEN 'derived' END`,\n );\n } else {\n // A docs-only column: no source states it, so the document always wins.\n selects.push(`${assertedValue} AS ${quoteIdent(field)}`);\n origin.push(`${sqlString(field)}, CASE WHEN ${asserted} THEN 'asserted' END`);\n }\n }\n selects.push(\n `json_patch('{}', json_object(${origin.join(\", \")})) AS ${quoteIdent(ORIGIN_COLUMN)}`,\n );\n selects.push(`r.${quoteIdent(SOURCES_COLUMN)} AS ${quoteIdent(SOURCES_COLUMN)}`);\n\n db.exec(\n `CREATE VIEW ${RESOLVED_VIEW} AS SELECT ${selects.join(\", \")} FROM docs d LEFT JOIN ${DERIVED_ROWS} r USING (${quoteIdent(\"_path\")})`,\n );\n}\n\n/** Where a table build stands: the run's directories and its config. */\nexport interface DeriveTableContext {\n cwd: string;\n base: string;\n configDir?: string;\n config: DocmetaConfig | null;\n /** Whether the GitHub or GitLab review cache may answer; `--no-cache` clears it. */\n cache: boolean;\n /** The clock an uncommitted body change is dated by; default `new Date()`. */\n now?: () => Date;\n}\n\n/**\n * Derive the table's rows: `fields` — what the caller's statements can read,\n * see `fieldsForSql`, plus `provenance` when `derive.fields` manages it — from the sources the config allows (all five when it\n * says nothing), with the review cache on. The view keeps every column, and\n * a field not derived is NULL in it; only a source some named field needs\n * is consulted, so a statement reading `owner` never spawns `gh`, and a\n * configured command runs only when its field is read. A requested source\n * that cannot answer is the run's error, never an empty column — the same\n * rule `validate` and `derive` follow — and `hint` is the caller's own way\n * out.\n */\nexport async function deriveForTable(\n inputs: readonly DeriveInput[],\n ctx: DeriveTableContext,\n hint: string,\n fields: readonly DerivableField[],\n): Promise<Map<string, DerivedRecord>> {\n const derive = ctx.config?.derive;\n const commands = commandsOf(derive);\n // `*` does not read `provenance` (its blame per page is paid only when\n // asked for), so a run whose `derive.fields` manages it asks here.\n const managesProvenance =\n derive?.fields?.includes(PROVENANCE_FIELD) === true && !fields.includes(PROVENANCE_FIELD);\n const result = await deriveMetadata(inputs, {\n cwd: ctx.cwd,\n base: ctx.base,\n ...(ctx.configDir !== undefined ? { configDir: ctx.configDir } : {}),\n sources: derive?.sources ?? [...DERIVE_SOURCES],\n fields: managesProvenance ? [...fields, PROVENANCE_FIELD] : fields,\n ...(derive?.codeowners !== undefined ? { codeowners: derive.codeowners } : {}),\n ...(commands !== undefined ? { commands } : {}),\n cache: ctx.cache,\n now: ctx.now ?? (() => new Date()),\n machines: machinesOf(derive),\n });\n assertSourcesAvailable(result.sources, hint);\n return result.records;\n}\n","/**\n * Named corpus checks (proposal 0026): SQL from the config's `checks:` list,\n * run over the same `docs` projection `query` builds, whose result rows are\n * **findings** rather than a table.\n *\n * The column convention is the whole mapping: `path` (required) names the file\n * a finding attaches to, `line` its 1-based source line, `key` the metadata\n * field at fault (it becomes the `instancePath`, and with it part of the\n * finding's baseline identity), `message` the prose. A row that follows it\n * becomes an ordinary `FieldError` — `schema: \"check:<name>\"`, `keyword:\n * \"check\"` — and every downstream surface (pretty, github, SARIF, JUnit, the\n * baseline ratchet) works unchanged.\n */\nimport { DocmetaError, type FieldError } from \"../types.js\";\nimport { CHECK_NAME, type CheckConfig } from \"./config.js\";\nimport { escapePointerSegment } from \"../extractors/pointer.js\";\nimport {\n assertSingleStatement,\n collectNamedParameters,\n corpusDataColumns,\n createDocsTable,\n loadSqlite,\n registerLineFor,\n stripLeadingTrivia,\n type ProjectionEntry,\n} from \"./projection.js\";\nimport {\n collectCollections,\n createCollectionViews,\n type CollectionParams,\n} from \"./collections.js\";\nimport {\n createDerivedView,\n createResolvedView,\n derivedColumns,\n fieldsForSql,\n mentionsDerived,\n mentionsResolved,\n} from \"./derive/table.js\";\nimport {\n derivableFields,\n type DerivableField,\n type DeriveCommand,\n type DerivedRecord,\n} from \"./derive/types.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\n\n/** One loaded file a check may attach findings to. */\nexport type CheckEntry = ProjectionEntry;\n\n/** The `keyword` every check finding carries: no Ajv keyword produced it. */\nexport const CHECK_KEYWORD = \"check\";\n\n/**\n * The `schema` ref a check's findings carry — and their baseline identity.\n *\n * The grammar is asserted here as well as in the config parser: a\n * programmatic `CheckConfig` never passes through `parseChecks`, and a\n * path-shaped name (`../evil`, `slugs.json`) would classify as a file ref and\n * fingerprint cwd-relative — the identity bug `CHECK_NAME` exists to prevent.\n */\nexport function checkSchemaRef(name: string): string {\n if (!CHECK_NAME.test(name) || name.toLowerCase().endsWith(\".json\")) {\n throw new DocmetaError(\n `check name \"${name}\" must match [a-z0-9][a-z0-9._-]* and not end in \".json\" — the name is part of each finding's identity (check:<name>).`,\n );\n }\n return `check:${name}`;\n}\n\n/** The columns the convention consumes; everything else feeds the message. */\nconst CONVENTION_COLUMNS = new Set([\"path\", \"line\", \"key\", \"message\"]);\n\n/**\n * Map one check's result rows to findings, keyed by file path.\n *\n * `loaded` is the set of paths this run holds extractions for. A row naming\n * any other path is a broken check, not a finding: fabricating a result for a\n * file the run never read would corrupt the summary, so it refuses (exit 2)\n * with the check named — the same class as SQL that does not prepare. On the\n * `query --check` path no set is passed: the SELECT is the user's own, its\n * `path` column is taken at its word (`<stdin>` included — proposal 0026\n * § stress test 7), and only a non-string path refuses.\n */\nexport function rowsToFindings(\n name: string,\n columns: readonly string[],\n rows: readonly Record<string, unknown>[],\n loaded?: ReadonlySet<string>,\n): Map<string, FieldError[]> {\n if (!columns.includes(\"path\")) {\n throw new DocmetaError(\n `check \"${name}\": the result has no \\`path\\` column. A check's SELECT names its findings through the column convention: \\`path\\` (required), and optionally \\`line\\`, \\`key\\`, and \\`message\\`; any other column is folded into the message.`,\n );\n }\n const findings = new Map<string, FieldError[]>();\n const extras = columns.filter((c) => !CONVENTION_COLUMNS.has(c));\n for (const row of rows) {\n const path = row.path;\n if (typeof path !== \"string\" || (loaded !== undefined && !loaded.has(path))) {\n throw new DocmetaError(\n `check \"${name}\": a result row names ${JSON.stringify(path)}, which this run did not load — a finding must attach to a file of the corpus. Fix the check's \\`path\\` column.`,\n );\n }\n const key = typeof row.key === \"string\" && row.key !== \"\" ? row.key : undefined;\n const line = asLine(row.line);\n const message =\n typeof row.message === \"string\" && row.message !== \"\"\n ? row.message\n : synthesizeMessage(extras, row);\n const err: FieldError = {\n schema: checkSchemaRef(name),\n keyword: CHECK_KEYWORD,\n // RFC 6901 escaping, or a key containing `/` or `~` would build a\n // pointer that parses as a different (nested) location.\n instancePath: key === undefined ? \"\" : `/${escapePointerSegment(key)}`,\n message,\n ...(line === undefined ? {} : { line }),\n };\n const bucket = findings.get(path);\n if (bucket) bucket.push(err);\n else findings.set(path, [err]);\n }\n return findings;\n}\n\n/** A `line` cell, when it is the 1-based positive integer the contract means. */\nfunction asLine(value: unknown): number | undefined {\n const n =\n typeof value === \"bigint\" ? Number(value) : typeof value === \"number\" ? value : undefined;\n return n !== undefined && Number.isInteger(n) && n > 0 ? n : undefined;\n}\n\n/**\n * The fallback prose when a check declares no `message`: `col=value` over the\n * remaining columns, so a lazy `SELECT _path AS path, slug FROM …` is still\n * usable — not so it is a good idea; write a message. A NULL cell says\n * nothing, so it is omitted rather than rendered as a literal `null`; when\n * every remaining cell is NULL the generic fallback stands.\n */\nfunction synthesizeMessage(\n extras: readonly string[],\n row: Record<string, unknown>,\n): string {\n const pairs = extras.flatMap((c) => {\n const value = row[c];\n if (value === null || value === undefined) return [];\n // SQL cells are string | number | bigint (a BLOB cannot arise from the\n // projection's text/numeric columns); the JSON fallback keeps a future\n // surprise printable rather than \"[object Object]\".\n const text =\n typeof value === \"string\"\n ? value\n : typeof value === \"number\" || typeof value === \"bigint\"\n ? String(value)\n : JSON.stringify(value);\n return [`${c}=${text}`];\n });\n return pairs.length > 0 ? pairs.join(\", \") : \"check matched\";\n}\n\n/**\n * Run every configured check over the corpus and merge their findings.\n *\n * The projection is the one `query` builds — same columns, same value\n * conventions — plus `lineFor(path, key)` so a check can carry a source line.\n * A check whose SQL cannot prepare, or whose rows break the column\n * convention, aborts the run with the check named: a broken rule is an\n * operational error, never a finding or a silent skip.\n */\n/**\n * The run context a check projection may need beyond the entries themselves:\n * the declared collections that become views, and the two directories\n * membership is arithmetic between (proposal 0041 rules 7 and 10). No\n * resolution inputs: a check's `FROM authors` means \"the files the authors\n * collection selects\", which is what the config says, and deciding it costs\n * nothing but string arithmetic. The shape IS `CollectionParams`: it is handed\n * to `collectCollections` verbatim, and an intersection is what keeps the two\n * from drifting apart field by field.\n *\n * `derive` is the one addition (proposal 0040): how to get the rows behind\n * the `derived` and `resolved` tables when a check names either. A function\n * rather than the rows,\n * because building them spawns git, and a check that never names the table\n * must not pay for it. It is handed the fields the checks can read, so a\n * caller deriving from scratch consults only the sources those need; a\n * caller that already derived more may hand back what it has. Absent, a\n * check naming the table is refused.\n */\nexport type CheckRunContext = CollectionParams & {\n derive?: (\n fields: readonly DerivableField[],\n ) => Promise<ReadonlyMap<string, DerivedRecord>>;\n /**\n * The configured commands (proposal 0042), whose keys are columns of the\n * `derived` table beside the built-ins. Handed over rather than read from a\n * config, because since proposal 0041 a check's context carries none.\n */\n commands?: Readonly<Record<string, DeriveCommand>>;\n};\n\nexport async function runChecks(\n checks: readonly CheckConfig[],\n entries: readonly CheckEntry[],\n ctx: CheckRunContext = {},\n): Promise<Map<string, FieldError[]>> {\n const merged = new Map<string, FieldError[]>();\n if (checks.length === 0) return merged;\n\n const { DatabaseSync } = await loadSqlite();\n const db = new DatabaseSync(\":memory:\");\n try {\n // The one column list both `docs` and `resolved` are built from: the\n // view's asserted side reads those columns by name, so a second call\n // could not be allowed to disagree with the table's.\n const dataColumns = corpusDataColumns(entries);\n createDocsTable(db, entries, dataColumns);\n registerLineFor(db, entries);\n createCollectionViews(db, collectCollections(entries, ctx));\n // The derived channel's tables (0040), when any check names one: the same\n // views `query` builds, over the union of the fields those checks can\n // read. Either name builds both — `resolved` is `docs` joined to the same\n // rows — so a check reading the effective value costs the same one\n // derivation. Before `query_only`, since building them loads a table.\n const wantsDerived = checks.filter(\n (c) => mentionsDerived(c.query) || mentionsResolved(c.query),\n );\n if (wantsDerived.length > 0) {\n if (ctx.derive === undefined) {\n throw new DocmetaError(\n `check \"${wantsDerived[0]?.name ?? \"\"}\": the SQL names the derived or resolved table, but this run cannot derive. Run it through \\`manni meta validate\\`, or drop the reference.`,\n );\n }\n // The run's columns: the built-ins and the configured command keys\n // (0042), handed over by the caller that read the config.\n const commands = ctx.commands;\n const readable = derivableFields(commands);\n const fields = new Set<DerivableField>();\n for (const c of wantsDerived) for (const f of fieldsForSql(c.query, readable)) fields.add(f);\n createDerivedView(db, await ctx.derive([...fields]), derivedColumns(commands));\n createResolvedView(db, dataColumns, commands);\n }\n // Checks are SELECT-only by design — 0021's original discipline, which\n // 0022 lifted for `query` because writes became query's *feature*, judged\n // by its effect gate. Checks have no such gate: without this, an UPDATE\n // in one check mutates the shared projection every later check computes\n // over, and a DELETE/DROP is misdiagnosed downstream. Set after the\n // table and views are built, before any check's SQL runs.\n db.exec(\"PRAGMA query_only = 1\");\n const loaded = new Set(entries.map((e) => e.label));\n\n for (const check of checks) {\n // ATTACH and VACUUM write files of their own, which `query_only`\n // does not fully prevent (ATTACH creates the attached file; VACUUM\n // INTO creates its target before the engine refuses) — the same two\n // statements `query` refuses by name.\n const head = stripLeadingTrivia(check.query);\n if (/^(attach|vacuum)\\b/i.test(head)) {\n throw new DocmetaError(\n `check \"${check.name}\": ${head.split(/\\s/, 1)[0]?.toUpperCase() ?? \"that statement\"} is refused: it can write outside the docs table.`,\n );\n }\n // Checks bind nothing, so any named parameter would silently bind\n // NULL, match nothing, and green the gate forever — the false-green\n // shape the query-side guard refuses with a bind; here the remedy is\n // to inline the value.\n let tokens: string[];\n try {\n tokens = collectNamedParameters(check.query);\n } catch (err) {\n // The scan's own refusal (one name under two prefixes), check named.\n throw new DocmetaError(\n `check \"${check.name}\": ${errorMessage(err)}`,\n );\n }\n if (tokens.length > 0) {\n throw new DocmetaError(\n `check \"${check.name}\": the SQL references ${tokens.join(\", \")}, but checks bind no parameters — an unbound name binds NULL and matches nothing, so the gate would pass on a typo. Inline the value in the SQL.`,\n );\n }\n let columns: string[];\n let rows: Record<string, unknown>[];\n try {\n assertSingleStatement(check.query);\n const stmt = db.prepare(check.query);\n columns = stmt.columns().map((c) => c.name);\n rows = stmt.all();\n } catch (err) {\n const message = errorMessage(err);\n throw new DocmetaError(\n message.includes(\"attempt to write a readonly database\")\n ? `check \"${check.name}\": ${message} — checks are read-only by design; a check is a SELECT over the projection. Edit the corpus with \\`manni meta query\\` instead.`\n : `check \"${check.name}\": ${message}`,\n );\n }\n for (const [path, errs] of rowsToFindings(\n check.name,\n columns,\n rows,\n loaded,\n )) {\n const bucket = merged.get(path);\n if (bucket) bucket.push(...errs);\n else merged.set(path, errs);\n }\n }\n } finally {\n db.close();\n }\n return merged;\n}\n","/**\n * Where a page's `provenance` record lives (proposal 0046 § In an external\n * manifest): in the page's frontmatter, or in the external-metadata manifest\n * of a collection the page belongs to, when that manifest owns the key.\n *\n * `derive` writes the record there, and every reader that compares it (the\n * derive command, `validate`, `get`) hands the same manifest to the git\n * source, so evidence rule 2 reads the manifest's blob at each commit rather\n * than the page's frontmatter. Membership is decided by every declared\n * collection, as cite decides it for `citations`: a page named by path is\n * still a member of the collection whose manifest holds its record.\n */\nimport { isAbsolute, relative, resolve, sep } from \"node:path\";\nimport {\n ownsKey,\n type CollectionConfig,\n type ExternalMetadataConfig,\n} from \"../../../shared/collections.js\";\nimport { hasPagePlaceholder, pageManifestPath } from \"../../../shared/page-manifest.js\";\nimport { DocmetaError } from \"../../types.js\";\nimport { memberOf } from \"../collections.js\";\nimport { externalMetadataJoin, outsideRefusal, PATH_JOIN, reportedPath } from \"../external-metadata.js\";\nimport { classifyRef } from \"../schema-registry.js\";\nimport {\n PROVENANCE_FIELD,\n STAMPED_DATE_FIELDS,\n type ManifestRef,\n type StampedDateField,\n} from \"./types.js\";\n\n/** A manifest that owns `provenance` for one collection. */\nexport interface ProvenanceManifest {\n collection: string;\n /**\n * The manifest file, absolute. For a `{page}` manifest (proposal 0058) as\n * `provenanceManifests` lists it, the pattern resolved as a path; a place\n * carries the page's own file.\n */\n absPath: string;\n /** The manifest as the run reports it: relative to the run's base, posix. The pattern as written, for a `{page}` manifest before placing. */\n file: string;\n /** `path`, or the page field the manifest joins on. */\n join: string;\n /** `file:` holds `{page}`, so each page keeps its record in a manifest of its own. */\n perPage: boolean;\n /** `file:` as the config writes it, which a `{page}` manifest resolves per page. */\n written: string;\n /**\n * The manifest names no `keys` (proposal 0068), so it holds a page's record\n * only when the page's schemas mark `provenance` external. The declaration,\n * for `ownsKey`.\n */\n implied?: { collection: CollectionConfig; manifest: ExternalMetadataConfig; url: boolean };\n}\n\n/** One page's record in a manifest. */\nexport interface ProvenancePlace extends ManifestRef {\n manifest: ProvenanceManifest;\n}\n\nconst toPosix = (p: string): string => p.split(sep).join(\"/\");\n\n/**\n * Every declared manifest that owns `provenance`, or may: a manifest with no\n * `keys` (proposal 0068) owns it for the pages whose schemas mark it. A URL\n * manifest may not own it: `derive` writes the record, and a URL is not\n * somewhere to write. One that names it is refused here, and a keyless one\n * when a page's marks give it the record.\n */\nexport function provenanceManifests(\n collections: readonly CollectionConfig[],\n configDir: string,\n base: string,\n field: string = PROVENANCE_FIELD,\n): ProvenanceManifest[] {\n const out: ProvenanceManifest[] = [];\n for (const collection of collections) {\n for (const manifest of collection.externalMetadata) {\n const implied = manifest.keys === undefined;\n if (!implied && manifest.keys?.includes(field) !== true) continue;\n const url = classifyRef(manifest.file).kind === \"url\";\n if (url && !implied) throw new DocmetaError(urlRefusal(collection.name, field));\n if (url) {\n out.push({\n collection: collection.name,\n absPath: manifest.file,\n file: manifest.file,\n join: externalMetadataJoin(manifest),\n perPage: false,\n written: manifest.file,\n implied: { collection, manifest, url },\n });\n continue;\n }\n const absPath = isAbsolute(manifest.file) ? manifest.file : resolve(configDir, manifest.file);\n const perPage = hasPagePlaceholder(manifest.file);\n out.push({\n collection: collection.name,\n absPath,\n file: perPage ? manifest.file : reportedPath(absPath, base),\n join: externalMetadataJoin(manifest),\n perPage,\n written: manifest.file,\n ...(implied ? { implied: { collection, manifest, url } } : {}),\n });\n }\n }\n return out;\n}\n\nfunction urlRefusal(collection: string, field: string): string {\n return `collection ${collection}: ${field} cannot come from a URL manifest, because manni meta derive writes it.`;\n}\n\n/**\n * The manifest entry holding one page's record, or undefined when the record\n * is the page's own. A page in two collections whose manifests both own\n * `provenance` is refused: a writer has to know which file to write to.\n * `data` is the page's own metadata, for a manifest joined on a field; a page\n * that does not carry that field has no entry to write to, and is refused.\n * `marked` is what the page's schemas mark external, which decides whether a\n * manifest with no `keys` holds the record (proposal 0068).\n */\nexport function provenancePlace(\n label: string,\n data: Readonly<Record<string, unknown>>,\n manifests: readonly ProvenanceManifest[],\n collections: readonly CollectionConfig[],\n configDir: string,\n base: string,\n marked?: ReadonlySet<string>,\n field: string = PROVENANCE_FIELD,\n): ProvenancePlace | undefined {\n if (manifests.length === 0) return undefined;\n const members = new Set(memberOf(collections, configDir, base, label));\n const owning = manifests.filter(\n (m) =>\n members.has(m.collection) &&\n (m.implied === undefined || ownsKey(m.implied.collection, m.implied.manifest, field, marked)),\n );\n const [declared, second] = owning;\n if (declared === undefined) return undefined;\n if (second !== undefined) {\n throw new DocmetaError(\n `${label} is in collections ${declared.collection} and ${second.collection}, and both keep ${field} in a manifest.`,\n );\n }\n if (declared.implied?.url === true) throw new DocmetaError(urlRefusal(declared.collection, field));\n const manifest = declared.perPage ? ownManifest(declared, label, collections, configDir, base) : declared;\n if (manifest.join === PATH_JOIN) {\n const entry = toPosix(relative(configDir, resolve(base, label)));\n return { manifest, absPath: manifest.absPath, entry, join: manifest.join };\n }\n const value = data[manifest.join];\n if (typeof value !== \"string\" && typeof value !== \"number\") {\n throw new DocmetaError(\n `${label} carries no ${manifest.join}, which ${manifest.file} joins on, so its ${field} has no entry there.`,\n );\n }\n return { manifest, absPath: manifest.absPath, entry: String(value), join: manifest.join };\n}\n\n/**\n * A `{page}` manifest (proposal 0058) as one page keeps its record: the\n * page's own file. A page above the config directory cannot have one, which\n * the loader refuses first whenever the run names the page.\n */\nfunction ownManifest(\n manifest: ProvenanceManifest,\n label: string,\n collections: readonly CollectionConfig[],\n configDir: string,\n base: string,\n): ProvenanceManifest {\n const resolved = pageManifestPath(manifest.written, configDir, resolve(base, label));\n if (\"outside\" in resolved) {\n const declared = collections\n .find((c) => c.name === manifest.collection)\n ?.externalMetadata.find((m) => m.file === manifest.written);\n throw new DocmetaError(\n outsideRefusal(declared ?? { file: manifest.written }, manifest.collection, resolved.pageRel),\n );\n }\n return { ...manifest, absPath: resolved.abs, file: reportedPath(resolved.abs, base) };\n}\n\n/**\n * `provenanceManifests` for a reader (`validate`, `get`): nothing is\n * written, so a URL manifest is not refused here; its record is simply not\n * read at a commit.\n */\nexport function readerManifests(\n collections: readonly CollectionConfig[],\n configDir: string,\n base: string,\n field: string = PROVENANCE_FIELD,\n): ProvenanceManifest[] {\n const local = collections.map((c) => ({\n ...c,\n externalMetadata: c.externalMetadata.filter((m) => classifyRef(m.file).kind !== \"url\"),\n }));\n return provenanceManifests(local, configDir, base, field);\n}\n\n/**\n * `provenancePlace` for a reader: a page the writer would refuse (two\n * owning manifests, a join field it lacks) has no manifest to read at a\n * commit, and the merge already reports what is wrong with it.\n */\nexport function readerPlace(\n label: string,\n data: Readonly<Record<string, unknown>>,\n manifests: readonly ProvenanceManifest[],\n collections: readonly CollectionConfig[],\n configDir: string,\n base: string,\n marked?: ReadonlySet<string>,\n field: string = PROVENANCE_FIELD,\n): ManifestRef | undefined {\n try {\n const place = provenancePlace(label, data, manifests, collections, configDir, base, marked, field);\n return place === undefined ? undefined : { absPath: place.absPath, entry: place.entry, join: place.join };\n } catch (err) {\n if (err instanceof DocmetaError) return undefined;\n throw err;\n }\n}\n\n/**\n * The manifests that own a page's `created` and `last-updated`, for the git\n * source to read the stamp a fact commit carries there (proposal 0069, rule\n * 1). Read as `readerPlace` reads provenance's: nothing is written through\n * these, so a page the writer would refuse simply has no manifest to read.\n * `fields` narrows the reads to the dated fields the run manages.\n */\nexport function stampManifests(\n label: string,\n data: Readonly<Record<string, unknown>>,\n collections: readonly CollectionConfig[],\n configDir: string,\n base: string,\n marked: ReadonlySet<string> | undefined,\n fields: readonly string[],\n): Partial<Record<StampedDateField, ManifestRef>> {\n const out: Partial<Record<StampedDateField, ManifestRef>> = {};\n for (const field of STAMPED_DATE_FIELDS) {\n if (!fields.includes(field)) continue;\n const manifests = readerManifests(collections, configDir, base, field);\n const place = readerPlace(label, data, manifests, collections, configDir, base, marked, field);\n if (place !== undefined) out[field] = place;\n }\n return out;\n}\n","/**\n * Option plumbing every tool's commander wrapper needs.\n *\n * These are the pieces of `src/meta/cli.ts` that had nothing to do with\n * metadata: how a repeatable flag accumulates, how a comma list splits, how\n * stdin is drained, how `-c`/`--no-config` share one attribute, and how a\n * `--no-<thing>` flag is kept from clobbering a config value it never meant to\n * touch. A sibling tool that re-derived any of these would get one of them\n * subtly different, and \"commands must have parallel behaviors\" is the rule\n * that says it must not.\n */\nimport { basename, relative } from \"node:path\";\n\n/** Accumulate a repeatable option (`--exclude a --exclude b`). */\nexport function collect(value: string, prev: string[]): string[] {\n return prev.concat([value]);\n}\n\n/** Split a comma-separated option value, dropping blanks. */\nexport function splitList(value: string): string[] {\n return value\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\n/**\n * What a run that reads `-` without `--as` is told. Stdin has no file name to\n * pick a parser by, so the user names the format. One sentence for every tool\n * that reads stdin, so the refusal reads the same wherever it is hit.\n */\nexport const STDIN_REQUIRES_AS =\n \"Reading from stdin (`-`) requires --as <format> to choose an extractor.\";\n\n/** Drain stdin to a UTF-8 string. */\nexport async function readStdin(): Promise<string> {\n const chunks: Buffer[] = [];\n for await (const chunk of process.stdin) chunks.push(chunk as Buffer);\n return Buffer.concat(chunks).toString(\"utf8\");\n}\n\n/**\n * Split the one commander attribute that `-c, --config <path>` and\n * `--no-config` share. Verified by experiment: `opts.config` is `undefined`\n * with neither flag, the string with `-c`, and `false` with `--no-config`.\n */\nexport function configOption(value: unknown): {\n configPath?: string;\n noConfig?: boolean;\n} {\n if (value === false) return { noConfig: true };\n return typeof value === \"string\" ? { configPath: value } : {};\n}\n\n/**\n * A `--no-<thing>` flag for the core: only an explicit false travels.\n *\n * Commander gives `true` when the flag is absent, but that is its *default*,\n * not a choice the user made — passing it on would override the config's own\n * answer (`respectGitignore:`, say). Only the explicit `false` travels; absence\n * stays `undefined` so config still decides.\n */\nexport function explicitFalse(value: unknown): boolean | undefined {\n return value === false ? false : undefined;\n}\n\n/**\n * Say which config governed the run, and where it came from.\n *\n * Discovery walks up to the project boundary, so the answer is no longer\n * obvious from the working directory, and an unexpected ancestor config is the\n * difference between a five-minute diagnosis and an hour of confusion. Goes to\n * stderr for anything a machine reads, so structured output stays parseable.\n */\nexport function reportConfig(\n toStdout: boolean,\n cwd: string,\n): (info: { path: string; dir: string }) => void {\n return (info) => {\n const where = (relative(cwd, info.dir) || \".\").replace(/\\\\/g, \"/\");\n const line = `Using ${basename(info.path)} (${where})\\n`;\n (toStdout ? process.stdout : process.stderr).write(line);\n };\n}\n"],"mappings":"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","names":["readFile","readFile","relative","resolve","isMap","parseDocument","at","text","readFile","basename","dirname","join","resolve","text","errorCode","readFile","text","path","join","basename","dirname","count","items","posix","relative","join","text","resolve","list","at","readFile","parseDocument","isMap","memberOf","isRecord","at","memberOf","readFile","stat","basename","isAbsolute","join","relative","resolve","sep","LineCounter","isMap","isNode","isScalar","isSeq","parseYaml","parseDocument","isAbsolute","relative","sep","j","tokens","text","relative","sep","isAbsolute","list","posix","LineCounter","isMap","isNode","isScalar","parseDocument","stringify","text","join","at","line","LineCounter","parseDocument","posix","isScalar","isMap","isNode","isRecord","r","stringify","run","sep","reported","relative","basename","isAbsolute","resolve","join","posix","rel","stat","at","unreadable","readFile","text","keyLines","LineCounter","parseDocument","isMap","isScalar","isNode","isSeq","list","parseYaml","steps","resolve","extname","picomatch","text","text","count","space","picomatch","blank","dirname","resolve","join","isRecord","readFile","dirname","relative","resolve","sep","picomatch","resolve","text","owners","picomatch","dirname","toPosix","relative","readFile","sep","settle","text","text","resolvePath","segments","project","isRecord","resolvePath","spawn","dirname","extname","isAbsolute","posix","relative","sep","parseYaml","items","run","dirname","relative","sep","text","histories","at","manifestStamp","utcDate","short","entry","isAbsolute","posix","join","parseYaml","isRecord","extname","settle","spawn","git","dirname","unavailable","resolve","text","tokens","isAbsolute","relative","resolve","sep","toPosix","sep","isAbsolute","resolve","relative","basename","relative","run","resolve","join","at","provenanceManifests","own","readFile","extname","reported","count"]}
|