feat(notion-md): v-next frictionless, progressively-disclosed sync (#774)#775
feat(notion-md): v-next frictionless, progressively-disclosed sync (#774)#775schickling-assistant wants to merge 21 commits into
Conversation
Storybook PreviewsNo storybooks were deployed. |
CI Measurementspartial - advisory gate - readiness
nix / closures / packages
Unchanged / 0-impact measurements (17)These rows had compatible baseline data, but their semantic impact rounded to 0.00x because the movement was below the configured budget, below the noise floor, or inside the robust noise band. devenv / devenv cli
devenv / devenv shell
devenv / genie
devenv / quality gates
devenv / workspace setup
nix / closures / packages
Diagnostic / ungated measurements (7)source / effect-utils
devenv / devenv shell
All measurements
Previous runs
Source-of-truth JSON{
"schemaVersion": 1,
"title": "CI Measurements",
"status": "partial",
"gate": "advisory",
"readiness": "partial (17/26 enabled observations gateable)",
"commit": {
"shortSha": "b2a645f",
"sha": "b2a645fbe18885d24b3f7418e17cbdf4eafea9af"
},
"run": {
"id": "27512898824",
"attempt": "1",
"url": "https://github.com/overengineeringstudio/effect-utils/actions/runs/27512898824"
},
"baseline": null,
"protocol": "devenv-perf-warm-median-v2",
"chart": {
"meaning": "semantic-impact",
"zeroImpactMeaning": "no actionable PR impact after budgets, noise floor, and robust evidence checks",
"svg": "https://raw.githubusercontent.com/overengineeringstudio/effect-utils/ci-measurement-assets/ci-measurements/pr-775/b2a645fbe18885d24b3f7418e17cbdf4eafea9af/run-27512898824-attempt-1/ci-measurements.svg",
"lightPng": "https://raw.githubusercontent.com/overengineeringstudio/effect-utils/ci-measurement-assets/ci-measurements/pr-775/b2a645fbe18885d24b3f7418e17cbdf4eafea9af/run-27512898824-attempt-1/ci-measurements.png",
"darkPng": "https://raw.githubusercontent.com/overengineeringstudio/effect-utils/ci-measurement-assets/ci-measurements/pr-775/b2a645fbe18885d24b3f7418e17cbdf4eafea9af/run-27512898824-attempt-1/ci-measurements-dark.png"
},
"measurements": [
{
"id": "nix.closure.nar_size",
"label": "Total closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"genie",
"total",
"closure-size",
"nix closure"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 561373688,
"current": 561922280,
"delta": 548592,
"ratio": 1.0009772314088223,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10678881.76,
"evidenceDeltaUpper": 11776065.76,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "total"
}
},
{
"id": "nix.closure.serialized_nar_size",
"label": "Total serialized NAR size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"genie",
"total",
"serialized-nar-size",
"nix closure diagnostics"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "pass",
"direction": "regressed",
"gateable": true,
"gateReason": "eligible",
"confidence": "within_budget",
"comparisonMode": "diagnostic",
"unit": "bytes",
"baseline": 561373688,
"current": 561922280,
"delta": 548592,
"ratio": 1.0009772314088223,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 20,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -55588776.800000004,
"evidenceDeltaUpper": 56685960.800000004,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "total",
"sizeKind": "nar"
}
},
{
"id": "nix.closure.nar_size",
"label": "Total closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"megarepo",
"total",
"closure-size",
"nix closure"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 151364760,
"current": 151426200,
"delta": 61440,
"ratio": 1.000405906896691,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10424320,
"evidenceDeltaUpper": 10547200,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "total"
}
},
{
"id": "nix.closure.serialized_nar_size",
"label": "Total serialized NAR size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"megarepo",
"total",
"serialized-nar-size",
"nix closure diagnostics"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "pass",
"direction": "regressed",
"gateable": true,
"gateReason": "eligible",
"confidence": "within_budget",
"comparisonMode": "diagnostic",
"unit": "bytes",
"baseline": 151364760,
"current": 151426200,
"delta": 61440,
"ratio": 1.000405906896691,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 20,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -15075036,
"evidenceDeltaUpper": 15197916,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "total",
"sizeKind": "nar"
}
},
{
"id": "nix.closure.nar_size",
"label": "Total closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"oxlint-npm",
"total",
"closure-size",
"nix closure"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 163874192,
"current": 163884208,
"delta": 10016,
"ratio": 1.0000611200572693,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10475744,
"evidenceDeltaUpper": 10495776,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "total"
}
},
{
"id": "nix.closure.serialized_nar_size",
"label": "Total serialized NAR size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"oxlint-npm",
"total",
"serialized-nar-size",
"nix closure diagnostics"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "pass",
"direction": "regressed",
"gateable": true,
"gateReason": "eligible",
"confidence": "within_budget",
"comparisonMode": "diagnostic",
"unit": "bytes",
"baseline": 163874192,
"current": 163884208,
"delta": 10016,
"ratio": 1.0000611200572693,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 20,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -16377403.200000001,
"evidenceDeltaUpper": 16397435.200000001,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "total",
"sizeKind": "nar"
}
},
{
"id": "source.lines",
"label": "Genie runtime lines",
"group": "source / effect-utils",
"path": [
"source",
"effect-utils",
"packages",
"genie",
"source / genie"
],
"groupPath": [
"source",
"effect-utils"
],
"status": "pass",
"direction": "regressed",
"gateable": false,
"gateReason": "disabled",
"confidence": "diagnostic",
"comparisonMode": "budget",
"unit": "lines",
"baseline": 19809,
"current": 20266,
"delta": 457,
"ratio": 1.023070321571003,
"semanticImpactScore": null,
"semanticImpactKind": "diagnostic",
"baselineSources": 22,
"currentSamples": 67,
"pairedSamples": 0,
"evidenceDeltaLower": -1523.9,
"evidenceDeltaUpper": 2437.9,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"scope": "genie_runtime"
}
},
{
"id": "source.lines",
"label": "Genie CI workflow helpers lines",
"group": "source / effect-utils",
"path": [
"source",
"effect-utils",
"genie",
"ci-workflow",
"source / ci"
],
"groupPath": [
"source",
"effect-utils"
],
"status": "pass",
"direction": "regressed",
"gateable": false,
"gateReason": "disabled",
"confidence": "diagnostic",
"comparisonMode": "budget",
"unit": "lines",
"baseline": 7318,
"current": 7418,
"delta": 100,
"ratio": 1.0136649357748018,
"semanticImpactScore": null,
"semanticImpactKind": "diagnostic",
"baselineSources": 22,
"currentSamples": 9,
"pairedSamples": 0,
"evidenceDeltaLower": -631.8000000000001,
"evidenceDeltaUpper": 831.8000000000001,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"scope": "genie_ci_workflow"
}
},
{
"id": "source.files",
"label": "Genie runtime files",
"group": "source / effect-utils",
"path": [
"source",
"effect-utils",
"packages",
"genie",
"source / genie"
],
"groupPath": [
"source",
"effect-utils"
],
"status": "pass",
"direction": "regressed",
"gateable": false,
"gateReason": "disabled",
"confidence": "diagnostic",
"comparisonMode": "budget",
"unit": "count",
"baseline": 66,
"current": 67,
"delta": 1,
"ratio": 1.0151515151515151,
"semanticImpactScore": null,
"semanticImpactKind": "diagnostic",
"baselineSources": 22,
"currentSamples": 67,
"pairedSamples": 0,
"evidenceDeltaLower": -5.6000000000000005,
"evidenceDeltaUpper": 7.6000000000000005,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"scope": "genie_runtime"
}
},
{
"id": "source.lines",
"label": "Nix workspace tools lines",
"group": "source / effect-utils",
"path": [
"source",
"effect-utils",
"nix",
"workspace-tools",
"source / nix"
],
"groupPath": [
"source",
"effect-utils"
],
"status": "pass",
"direction": "regressed",
"gateable": false,
"gateReason": "disabled",
"confidence": "diagnostic",
"comparisonMode": "budget",
"unit": "lines",
"baseline": 3631.5,
"current": 3632,
"delta": 0.5,
"ratio": 1.000137684152554,
"semanticImpactScore": null,
"semanticImpactKind": "diagnostic",
"baselineSources": 22,
"currentSamples": 14,
"pairedSamples": 0,
"evidenceDeltaLower": -362.65000000000003,
"evidenceDeltaUpper": 363.65000000000003,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"scope": "nix_workspace_tools"
}
},
{
"id": "task_check_quick_warm",
"label": "Warm cached check:quick",
"group": "devenv / quality gates",
"path": [
"devenv",
"quality gates",
"check:quick"
],
"groupPath": [
"devenv",
"quality gates"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "within_budget",
"comparisonMode": "paired",
"unit": "seconds",
"baseline": 3.416,
"current": 3.186,
"delta": -0.22999999999999998,
"ratio": 0.9326697892271663,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 5,
"currentSamples": 5,
"pairedSamples": 5,
"evidenceDeltaLower": -4.623,
"evidenceDeltaUpper": -0.074,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"workload": "cached-no-op",
"taskCacheMode": "warm",
"probe": "task_check_quick_warm",
"probeLabel": "Warm cached check:quick",
"status": 0,
"sampleCount": 11,
"warmupCount": 1,
"measuredSampleCount": 5,
"pairedSampleCount": 5,
"pairedOrderProtocol": "balanced-seeded-alternating-v1",
"pairedOrderSeed": "27512898824-1-be140ae0f449312fda432d6c80e5060eb6c3df29",
"measurementProtocol": "devenv-perf-warm-median-v2",
"aggregation": "median",
"phase": "warm",
"devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
"otelServiceName": "devenv-perf-ci"
}
},
{
"id": "task_check_quick_forced",
"label": "Forced check:quick",
"group": "devenv / quality gates",
"path": [
"devenv",
"quality gates",
"check:quick"
],
"groupPath": [
"devenv",
"quality gates"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "paired",
"unit": "seconds",
"baseline": 12.716,
"current": 12.75,
"delta": 0.034000000000000696,
"ratio": 1.0026737967914439,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 3,
"currentSamples": 3,
"pairedSamples": 3,
"evidenceDeltaLower": -0.035,
"evidenceDeltaUpper": 0.034,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"workload": "forced-task-cache",
"taskCacheMode": "refresh",
"probe": "task_check_quick_forced",
"probeLabel": "Forced check:quick",
"status": 0,
"sampleCount": 6,
"warmupCount": 0,
"measuredSampleCount": 3,
"pairedSampleCount": 3,
"pairedOrderProtocol": "balanced-seeded-alternating-v1",
"pairedOrderSeed": "27512898824-1-be140ae0f449312fda432d6c80e5060eb6c3df29",
"measurementProtocol": "devenv-perf-warm-median-v2",
"aggregation": "median",
"phase": "warm",
"devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
"otelServiceName": "devenv-perf-ci"
}
},
{
"id": "task_pnpm_install",
"label": "pnpm install task",
"group": "devenv / workspace setup",
"path": [
"devenv",
"workspace setup"
],
"groupPath": [
"devenv",
"workspace setup"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "paired",
"unit": "seconds",
"baseline": 0.631,
"current": 0.611,
"delta": -0.020000000000000018,
"ratio": 0.9683042789223455,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 5,
"currentSamples": 5,
"pairedSamples": 5,
"evidenceDeltaLower": -0.025,
"evidenceDeltaUpper": -0.012,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"probe": "task_pnpm_install",
"probeLabel": "pnpm install task",
"status": 0,
"sampleCount": 11,
"warmupCount": 1,
"measuredSampleCount": 5,
"pairedSampleCount": 5,
"pairedOrderProtocol": "balanced-seeded-alternating-v1",
"pairedOrderSeed": "27512898824-1-be140ae0f449312fda432d6c80e5060eb6c3df29",
"measurementProtocol": "devenv-perf-warm-median-v2",
"aggregation": "median",
"phase": "warm",
"devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
"otelServiceName": "devenv-perf-ci"
}
},
{
"id": "task_genie_run",
"label": "Genie run task",
"group": "devenv / genie",
"path": [
"devenv",
"genie"
],
"groupPath": [
"devenv",
"genie"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "paired",
"unit": "seconds",
"baseline": 1.134,
"current": 1.124,
"delta": -0.009999999999999787,
"ratio": 0.9911816578483247,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 5,
"currentSamples": 5,
"pairedSamples": 5,
"evidenceDeltaLower": -0.024,
"evidenceDeltaUpper": 0.011,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"probe": "task_genie_run",
"probeLabel": "Genie run task",
"status": 0,
"sampleCount": 11,
"warmupCount": 1,
"measuredSampleCount": 5,
"pairedSampleCount": 5,
"pairedOrderProtocol": "balanced-seeded-alternating-v1",
"pairedOrderSeed": "27512898824-1-be140ae0f449312fda432d6c80e5060eb6c3df29",
"measurementProtocol": "devenv-perf-warm-median-v2",
"aggregation": "median",
"phase": "warm",
"devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
"otelServiceName": "devenv-perf-ci"
}
},
{
"id": "genie_check_direct",
"label": "Genie check direct",
"group": "devenv / genie",
"path": [
"devenv",
"genie"
],
"groupPath": [
"devenv",
"genie"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "paired",
"unit": "seconds",
"baseline": 5.696,
"current": 5.705,
"delta": 0.009000000000000341,
"ratio": 1.0015800561797754,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 5,
"currentSamples": 5,
"pairedSamples": 5,
"evidenceDeltaLower": -0.025,
"evidenceDeltaUpper": 0.014,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"probe": "genie_check_direct",
"probeLabel": "Genie check direct",
"status": 0,
"sampleCount": 11,
"warmupCount": 1,
"measuredSampleCount": 5,
"pairedSampleCount": 5,
"pairedOrderProtocol": "balanced-seeded-alternating-v1",
"pairedOrderSeed": "27512898824-1-be140ae0f449312fda432d6c80e5060eb6c3df29",
"measurementProtocol": "devenv-perf-warm-median-v2",
"aggregation": "median",
"phase": "warm",
"devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
"otelServiceName": "devenv-perf-ci"
}
},
{
"id": "shell_eval_warm",
"label": "Warm shell eval",
"group": "devenv / devenv shell",
"path": [
"devenv",
"devenv shell"
],
"groupPath": [
"devenv",
"devenv shell"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "paired",
"unit": "seconds",
"baseline": 1.862,
"current": 1.871,
"delta": 0.008999999999999897,
"ratio": 1.0048335123523093,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 5,
"currentSamples": 5,
"pairedSamples": 5,
"evidenceDeltaLower": -0.021,
"evidenceDeltaUpper": 0.015,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"probe": "shell_eval_warm",
"probeLabel": "Warm shell eval",
"status": 0,
"sampleCount": 11,
"warmupCount": 1,
"measuredSampleCount": 5,
"pairedSampleCount": 5,
"pairedOrderProtocol": "balanced-seeded-alternating-v1",
"pairedOrderSeed": "27512898824-1-be140ae0f449312fda432d6c80e5060eb6c3df29",
"measurementProtocol": "devenv-perf-warm-median-v2",
"aggregation": "median",
"phase": "warm",
"devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
"otelServiceName": "devenv-perf-ci"
}
},
{
"id": "processes_help",
"label": "devenv processes --help",
"group": "devenv / devenv cli",
"path": [
"devenv",
"devenv cli"
],
"groupPath": [
"devenv",
"devenv cli"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "paired",
"unit": "seconds",
"baseline": 0.017,
"current": 0.017,
"delta": 0,
"ratio": 1,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 9,
"currentSamples": 9,
"pairedSamples": 9,
"evidenceDeltaLower": -0.001,
"evidenceDeltaUpper": 0.001,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"probe": "processes_help",
"probeLabel": "devenv processes --help",
"status": 0,
"sampleCount": 19,
"warmupCount": 1,
"measuredSampleCount": 9,
"pairedSampleCount": 9,
"pairedOrderProtocol": "balanced-seeded-alternating-v1",
"pairedOrderSeed": "27512898824-1-be140ae0f449312fda432d6c80e5060eb6c3df29",
"measurementProtocol": "devenv-perf-warm-median-v2",
"aggregation": "median",
"phase": "warm",
"devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
"otelServiceName": "devenv-perf-ci"
}
},
{
"id": "tasks_list",
"label": "devenv tasks list",
"group": "devenv / devenv cli",
"path": [
"devenv",
"devenv cli"
],
"groupPath": [
"devenv",
"devenv cli"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "paired",
"unit": "seconds",
"baseline": 0.038,
"current": 0.038,
"delta": 0,
"ratio": 1,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 9,
"currentSamples": 9,
"pairedSamples": 9,
"evidenceDeltaLower": -0.001,
"evidenceDeltaUpper": 0.001,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"probe": "tasks_list",
"probeLabel": "devenv tasks list",
"status": 0,
"sampleCount": 19,
"warmupCount": 1,
"measuredSampleCount": 9,
"pairedSampleCount": 9,
"pairedOrderProtocol": "balanced-seeded-alternating-v1",
"pairedOrderSeed": "27512898824-1-be140ae0f449312fda432d6c80e5060eb6c3df29",
"measurementProtocol": "devenv-perf-warm-median-v2",
"aggregation": "median",
"phase": "warm",
"devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
"otelServiceName": "devenv-perf-ci"
}
},
{
"id": "source.files",
"label": "Genie CI workflow helpers files",
"group": "source / effect-utils",
"path": [
"source",
"effect-utils",
"genie",
"ci-workflow",
"source / ci"
],
"groupPath": [
"source",
"effect-utils"
],
"status": "pass",
"direction": "unchanged",
"gateable": false,
"gateReason": "disabled",
"confidence": "diagnostic",
"comparisonMode": "budget",
"unit": "count",
"baseline": 9,
"current": 9,
"delta": 0,
"ratio": 1,
"semanticImpactScore": null,
"semanticImpactKind": "diagnostic",
"baselineSources": 22,
"currentSamples": 9,
"pairedSamples": 0,
"evidenceDeltaLower": -1,
"evidenceDeltaUpper": 1,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"scope": "genie_ci_workflow"
}
},
{
"id": "nix.closure.bucket.nar_size",
"label": "Nix sources closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"genie",
"buckets",
"nix-sources",
"nix closure buckets"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "unknown",
"direction": "unknown",
"gateable": false,
"gateReason": "missing_baseline",
"confidence": "unknown",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 0,
"current": 0,
"delta": 0,
"ratio": null,
"semanticImpactScore": null,
"semanticImpactKind": "unknown",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10485760,
"evidenceDeltaUpper": 10485760,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "nix-sources"
}
},
{
"id": "nix.closure.bucket.nar_size",
"label": "Nix sources closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"megarepo",
"buckets",
"nix-sources",
"nix closure buckets"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "unknown",
"direction": "unknown",
"gateable": false,
"gateReason": "missing_baseline",
"confidence": "unknown",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 0,
"current": 0,
"delta": 0,
"ratio": null,
"semanticImpactScore": null,
"semanticImpactKind": "unknown",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10485760,
"evidenceDeltaUpper": 10485760,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "nix-sources"
}
},
{
"id": "nix.closure.bucket.nar_size",
"label": "Nix sources closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"oxlint-npm",
"buckets",
"nix-sources",
"nix closure buckets"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "unknown",
"direction": "unknown",
"gateable": false,
"gateReason": "missing_baseline",
"confidence": "unknown",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 0,
"current": 0,
"delta": 0,
"ratio": null,
"semanticImpactScore": null,
"semanticImpactKind": "unknown",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10485760,
"evidenceDeltaUpper": 10485760,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "nix-sources"
}
},
{
"id": "source.files",
"label": "Nix workspace tools files",
"group": "source / effect-utils",
"path": [
"source",
"effect-utils",
"nix",
"workspace-tools",
"source / nix"
],
"groupPath": [
"source",
"effect-utils"
],
"status": "pass",
"direction": "unchanged",
"gateable": false,
"gateReason": "disabled",
"confidence": "diagnostic",
"comparisonMode": "budget",
"unit": "count",
"baseline": 14,
"current": 14,
"delta": 0,
"ratio": 1,
"semanticImpactScore": null,
"semanticImpactKind": "diagnostic",
"baselineSources": 22,
"currentSamples": 14,
"pairedSamples": 0,
"evidenceDeltaLower": -1.4000000000000001,
"evidenceDeltaUpper": 1.4000000000000001,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"scope": "nix_workspace_tools"
}
},
{
"id": "nix.closure.bucket.nar_size",
"label": "Node / pnpm closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"genie",
"buckets",
"node",
"nix closure buckets"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "unknown",
"direction": "unknown",
"gateable": false,
"gateReason": "missing_baseline",
"confidence": "unknown",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 0,
"current": 0,
"delta": 0,
"ratio": null,
"semanticImpactScore": null,
"semanticImpactKind": "unknown",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10485760,
"evidenceDeltaUpper": 10485760,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "node"
}
},
{
"id": "nix.closure.bucket.nar_size",
"label": "Node / pnpm closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"megarepo",
"buckets",
"node",
"nix closure buckets"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "unknown",
"direction": "unknown",
"gateable": false,
"gateReason": "missing_baseline",
"confidence": "unknown",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 0,
"current": 0,
"delta": 0,
"ratio": null,
"semanticImpactScore": null,
"semanticImpactKind": "unknown",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10485760,
"evidenceDeltaUpper": 10485760,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "node"
}
},
{
"id": "nix.closure.bucket.nar_size",
"label": "Node / pnpm closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"oxlint-npm",
"buckets",
"node",
"nix closure buckets"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "unknown",
"direction": "unknown",
"gateable": false,
"gateReason": "missing_baseline",
"confidence": "unknown",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 0,
"current": 0,
"delta": 0,
"ratio": null,
"semanticImpactScore": null,
"semanticImpactKind": "unknown",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10485760,
"evidenceDeltaUpper": 10485760,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "node"
}
},
{
"id": "nix.closure.bucket.nar_size",
"label": "Rust closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"genie",
"buckets",
"rust",
"nix closure buckets"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "unknown",
"direction": "unknown",
"gateable": false,
"gateReason": "missing_baseline",
"confidence": "unknown",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 0,
"current": 0,
"delta": 0,
"ratio": null,
"semanticImpactScore": null,
"semanticImpactKind": "unknown",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10485760,
"evidenceDeltaUpper": 10485760,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "rust"
}
},
{
"id": "nix.closure.bucket.nar_size",
"label": "Rust closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"megarepo",
"buckets",
"rust",
"nix closure buckets"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "unknown",
"direction": "unknown",
"gateable": false,
"gateReason": "missing_baseline",
"confidence": "unknown",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 0,
"current": 0,
"delta": 0,
"ratio": null,
"semanticImpactScore": null,
"semanticImpactKind": "unknown",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10485760,
"evidenceDeltaUpper": 10485760,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "rust"
}
},
{
"id": "nix.closure.bucket.nar_size",
"label": "Rust closure size",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"oxlint-npm",
"buckets",
"rust",
"nix closure buckets"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "unknown",
"direction": "unknown",
"gateable": false,
"gateReason": "missing_baseline",
"confidence": "unknown",
"comparisonMode": "budget",
"unit": "bytes",
"baseline": 0,
"current": 0,
"delta": 0,
"ratio": null,
"semanticImpactScore": null,
"semanticImpactKind": "unknown",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10485760,
"evidenceDeltaUpper": 10485760,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "rust"
}
},
{
"id": "nix.closure.path_count",
"label": "Total closure path count",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"genie",
"total",
"path-count",
"nix closure"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "budget",
"unit": "count",
"baseline": 79,
"current": 79,
"delta": 0,
"ratio": 1,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10,
"evidenceDeltaUpper": 10,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "total"
}
},
{
"id": "nix.closure.path_count",
"label": "Total closure path count",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"megarepo",
"total",
"path-count",
"nix closure"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "budget",
"unit": "count",
"baseline": 5,
"current": 5,
"delta": 0,
"ratio": 1,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10,
"evidenceDeltaUpper": 10,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "total"
}
},
{
"id": "nix.closure.path_count",
"label": "Total closure path count",
"group": "nix / closures / packages",
"path": [
"nix",
"closures",
"packages",
"oxlint-npm",
"total",
"path-count",
"nix closure"
],
"groupPath": [
"nix",
"closures",
"packages"
],
"status": "pass",
"direction": "unchanged",
"gateable": true,
"gateReason": "eligible",
"confidence": "noise_floor",
"comparisonMode": "budget",
"unit": "count",
"baseline": 8,
"current": 8,
"delta": 0,
"ratio": 1,
"semanticImpactScore": 0,
"semanticImpactKind": "neutral",
"baselineSources": 21,
"currentSamples": 1,
"pairedSamples": 0,
"evidenceDeltaLower": -10,
"evidenceDeltaUpper": 10,
"pairedEvidenceQuantile": 0.25,
"dimensions": {
"bucket": "total"
}
},
{
"id": "shell_eval_traced",
"label": "Shell eval with OTEL trace",
"group": "devenv / devenv shell",
"path": [
"devenv",
"devenv shell"
],
"groupPath": [
"devenv",
"devenv shell"
],
"status": "missing_baseline",
"direction": "unknown",
"gateable": false,
"gateReason": "missing_baseline",
"confidence": "missing_baseline",
"comparisonMode": "historical",
"unit": "seconds",
"baseline": null,
"current": 24.249,
"delta": null,
"ratio": null,
"semanticImpactScore": null,
"semanticImpactKind": null,
"baselineSources": 0,
"currentSamples": 1,
"pairedSamples": null,
"evidenceDeltaLower": null,
"evidenceDeltaUpper": null,
"pairedEvidenceQuantile": null,
"dimensions": {
"probe": "shell_eval_traced",
"probeLabel": "Shell eval with OTEL trace",
"status": 0,
"sampleCount": 2,
"warmupCount": 0,
"measuredSampleCount": 1,
"pairedSampleCount": 1,
"pairedOrderProtocol": "balanced-seeded-alternating-v1",
"pairedOrderSeed": "27512898824-1-be140ae0f449312fda432d6c80e5060eb6c3df29",
"measurementProtocol": "devenv-perf-warm-median-v2",
"aggregation": "median",
"phase": "warm",
"devenvRev": "2cf62a010000b70f15c78a72761fad7c9e6fb47a",
"otelServiceName": "devenv-perf-ci"
}
}
]
} |
The dispatch table's drift-REFUSE rows ("remote moved underneath", "local
hand-edited") are not realizable for single-source pages: with no stored base
(R31) the engine cannot distinguish "I edited" from "the other side moved" —
both are just `local ≢ remote`. Per R31/R32 the declared `source` decides the
winner unconditionally (local- or remote-authoritative mirror); concurrent-edit
detection/refusal is exclusively the `source: shared` story. Aligns the spec
with the implementation (PR #775) and the grilled statelessness invariant.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…osed sync Encode the settled design-grill conclusions into the notion-md VRS: - requirements.md: revise R09/R11 (base-snapshot + 3-way merge are source:shared-only; single-source push/pull is stateless live-reconcile), revise R26/R27 (real-Notion golden-corpus fidelity layer; fakes insufficient for fidelity), add R30 (adversarial footgun coverage) and R31-R36 (single-source statelessness, progressive disclosure, semantic- equivalence in-sync oracle, self-describing frontmatter dispatch, fidelity corpus, measurable simplicity bar). - spec.md: add a 'Target redesign (v-next)' section recording the candidate-to-beat 3-verb CLI, internal layering, the mandatory competing-designs bake-off, and a supersession map over the current model. Proposed vision.md delta (frictionless / progressive-disclosure north star) is recorded in the epic for human confirmation; vision.md is NOT edited here. Refs #774 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add two high-level value bullets to the vision: notion-md as a simple, elegant, reliable CLI for seamless authoring/collaboration/integration via local Markdown, and the three natural directions (local→Notion, Notion→local, bidirectional) as use cases. Keeps mechanism (statelessness, progressive disclosure) out of vision — those live in requirements/spec. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… bake-off Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…gate (#774) Add the self-describing `source: local|remote|shared` field (default `local`) to the `.nmd` V2 frontmatter (R34), with a struct-level filter enforcing that `remote`/`shared` files carry a `page_id` (null/absent ⇒ unbound create-on-push, legal only for `local`). Add `gateNmdLocalState`, the cross-file statelessness gate (R31/R32, DQ-2): it pairs a decoded frontmatter with its optional page-id-keyed sidecar and yields a tagged `NmdLocalState`. Single-source (`local`/`remote`) MUST NOT carry a stored base (sidecar) — a present base is a schema violation, making the stale-stored-base poisoned-noop class structurally unreachable. A bound `shared` file REQUIRES a base. Only the `shared-bound` branch exposes a `syncState`/base, so a single-source code path is structurally unable to construct a base. Decode + gate property/unit tests in `nmd.unit.test.ts`. Existing engine call sites set `source: 'local'` (current two-way behavior preserved; full source-aware dispatch lands in stage 3). Build + full notion-md (112) and notion-effect-client (131) suites green. Refs #774 (child 3) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ence keystone) (#774) Add a PURE `canonicalizer.ts` implementing DQ-VNEXT-1: the canonical normal form over the block-tree-rendered body, plus `semanticEqual` (equality of the normal form) and `canonicalHash` (the noop oracle for the stateless core). FOLDS presentation-only differences (the #756 churn class): emphasis-marker choice (`*`↔`_`, `**`↔`__`), ordered-list renumbering (`2.`→`1.`, item order preserved), loose↔tight list spacing, table-alignment/padding whitespace, trailing-whitespace + trailing-space hard breaks, and blank-line-run collapse. DOES NOT FOLD semantic/block-type differences (the #759/#763 fidelity shapes): heading level, heading-vs-paragraph type and adjacency, divider presence, code-fence language, and list item order. The relation is `===` over the normal form ⇒ reflexive/symmetric/transitive by construction. Property tests: idempotency (`canonicalize∘canonicalize == canonicalize`) over fast-check strings + samples, the relation laws, a table of #756-class cosmetic variant pairs all comparing EQUAL, and a table of #759/#763-class semantic shapes all comparing DISTINCT. Pure, no Notion. 28 tests; full notion-md suite (140) green. Refs #774 (children 3, 4) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eaf + tree orchestration (#774) Implement the three-layer internal design from the spec: - `reconcile-core.ts` — the STATELESS per-page core. `decideReconcile` maps the gated `NmdLocalState` + a live `render(local) ⇄ read(remote)` R33 compare to the dispatch outcome (`noop|create|push|pull|refuse|shared-defer`). Imports the canonicalizer ONLY — never the merge planner or a base read — so a single-source path is structurally unable to construct a base (R31/R32 by the dependency graph). `porcelainStatus` maps to git-porcelain words. - `reconcile-shared.ts` — the `source: shared` leaf, the SOLE importer of the merge planner (`tryMergeMarkdownBodies`) and the only base/3-way reasoning. `decideShared` ⇒ noop / merge / conflict; reached only via `shared-defer`. - `reconcile.ts` — the Effectful engine: read+gate local state, read remote, decide, apply. Single-source applies directly (create/push/pull) sending the canonical R33 body; `shared` defers to the leaf, writes `conflict.roughdraft`, and re-settles a fresh base after a clean apply. `statusFile` is read-only and safe by construction (no write path in its call graph, R30). `statusTree`/ `reconcileTree` map the core over discovered files via the now-exported `runBatch` (discovery + duplicate-page_id preflight + bounded concurrency). Tests: 17 pure decision unit tests (dispatch table, porcelain words, shared 3-way) + 9 FakeNotion control-flow e2e (create/push/pull/noop dispatch, #756 cosmetic churn folds to noop, canonical push reaches noop, status never mutates). Full notion-md suite (166) green. DESIGN NOTE — single-source push tie-break: the spec dispatch table's "local bound: remote moved underneath ⇒ REFUSE" row is not realizable statelessly (no stored base to distinguish "local changed" from "remote moved"). Per R11/R31 this implements: `source: local` bound ⇒ equivalent=noop, else push (local authority / mirror); the REFUSE-on-remote-drift safety is the `source: shared` story (the table even suggests `clone --as shared`). Flagged for confirmation. Refs #774 (children 3, 4) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the pre-redesign `status`/`plan`/`sync` surface with the decided three near-flagless verbs (spec "Decided surface"): - `clone <id|url> [path]` — the ONLY command taking a page id. Bootstraps a local `.nmd` from an existing Notion page via the new `clonePage` (added to reconcile.ts): writes self-describing frontmatter with `--as local|remote| shared` (default `remote`), fails closed on a lossy remote body, refuses to overwrite a file bound to a different page, and establishes the base sidecar for `--as shared`. - `status [path...]` — read-only, safe by construction; git-porcelain words (in-sync / local-ahead / remote-ahead / diverged / unbound) via `statusTree`, with `--json`. Emits the one-line "no push/pull — direction is each file's `source`" explainer. - `sync [path...]` — reconciles via `reconcileTree`; dispatch per file on frontmatter `source`, never on flags/arity. Flags: `--watch`/ `--poll-interval-ms`/`--recursive`/`--concurrency`/`--force`/`--json`. DROPPED (subsumed by frontmatter dispatch, R34): the `plan` verb, `--from-remote`, `--root`, `--root-file`, two-arg `sync`, and file-vs-tree flag branching. REVISED cli.e2e.test.ts deliberately: the old assertions encoded the superseded surface (`plan`/`--from-remote`/`--root`) and would contradict the decided spec; the new tests assert the three verbs, the `--as`/page-id `clone` contract, and that the dropped flags/verb are gone. `--watch` still delegates to the existing watch engine (legacy two-way) pending a watch port to the source-aware engine. Build + full notion-md suite (165) green. Refs #774 (children 3, 4) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…un + live smoke (R30/R35/R27) (#774) - `corpus.ts` + `corpus/fidelity-corpus.ts` — the golden fidelity corpus (R35): a Schema-decoded set of historically-broken Notion body shapes (#756 paragraph-after-list + emphasis/ordered-list churn, #763 paragraph↔heading, #759 divider, code-fence language) each pinning the R33 relation it must hold (`equal` ⇒ fidelity preserved/noop; `distinct_from` ⇒ shape not folded). Replayed OFFLINE in `corpus.unit.test.ts` so it gates every run with no network. `notion_round_trip` values are authored from the documented Notion normalizations and flagged `captured: pending-live-refresh` — the schema + replay harness are permanent; a credentialed capture run is a data refresh. - `adversarial-footgun.unit.test.ts` — the R30 zero-footgun pass. Each historical footgun has a test that ATTEMPTS to trigger it and asserts it is structurally impossible: poisoned-noop (a stored base on single-source is a schema violation; single-source gated states carry no `syncState`/base field), #756 cosmetic churn (semantically-equal pages reach noop), #759/#763 fidelity corruption (shapes stay canonically distinct), and wrong-direction push (`source: remote` has no push branch; bound-required `remote`/`shared`). All green ⇒ zero triggerable footguns. - `reconcile-live.integration.test.ts` — the thin REQUIRED live-smoke tier (R27): clone(remote) → status in-sync → reconcile noop against a real temporary page with archive cleanup. `skipIf`-gated on NOTION_API_TOKEN + NOTION_TEST_PARENT_PAGE_ID (same contract as live.integration.test.ts); compiles and skips cleanly without a test parent. Full notion-md suite 192 green (offline). Live capture/refresh of the corpus + the live-smoke run need a credentialed session with a dedicated test parent. Refs #774 (children 3, 4) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The dispatch table's drift-REFUSE rows ("remote moved underneath", "local
hand-edited") are not realizable for single-source pages: with no stored base
(R31) the engine cannot distinguish "I edited" from "the other side moved" —
both are just `local ≢ remote`. Per R31/R32 the declared `source` decides the
winner unconditionally (local- or remote-authoritative mirror); concurrent-edit
detection/refusal is exclusively the `source: shared` story. Aligns the spec
with the implementation (PR #775) and the grilled statelessness invariant.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8d11364 to
ca6d644
Compare
…ion) Provisional orchestrator decisions for landing the integrated Notion DB Markdown Sync VRS in #775: merge shape, live-test gating, shared property-write-core boundary, VRS authority, clean-break v1, execution model, done-bar, webhook/non-body boundaries. Each records principled options, trade-offs, evidence, and the chosen option for later ratification. Refs #775 #774. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Orchestration kickoff — autonomous milestone executionVerified-green baseline ( Current-state → VRS gap (sizing drives milestone order)
Execution order (dependency-driven)1 → 2 → 3 → 4 → 5 → (6 ∥ 7) → 8 sweep. Test scaffolding (Phase 8) lands incrementally with each feature, not as a final block. Each milestone: implement → Decisions of note (full rationale in the decision log): new Posted on behalf of @schickling
|
…ndation (#775 phase 1) Add the canonical shared property-identity layer all higher packages build on (VRS A03, R09-R14): - DataSourceId brand promoted to notion-effect-schema as the single canonical source; notion-datasource-sync core/domain.ts now aliases it. - PropertyDescriptor / PropertyDescriptors matching the .nmd property_descriptors shape (property_id, property_name, property_type, data_source_id, config_hash), with strict fail-closed decoders. - ConfigHash / SchemaHash distinctly-branded sha256 descriptor hashes. - PropertyIdentityEvidenceSource data-only union (descriptor | workspace_state | live_schema) — classification, not a proof carrier. - Deterministic canonical-JSON serialization for descriptor hashing. - 17 unit tests: strict decode accept/reject, canonical-JSON stability, brand validation, write-class consistency (computed/unsupported never writable). Schema package boundary kept strict: values/codecs/descriptors/ classification only; no authority, proof, or convergence. Refs #775 #774. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e hashing contract (#775 phase 1 review) Adversarial review of phase 1 found the descriptor canonicalizer invented a third serialization strategy (recursive codepoint key-sort) divergent from the package contract and corrupting non-plain values. - canonicalPropertyDescriptorJson now schema-encodes (deterministic struct field order) then plain JSON.stringify, matching canonical-codec.ts. - Drop the generic recursive canonicalDescriptorJson (no consumers). - Document decode* helpers as the sanctioned fail-closed entry points (bare Schema.Struct drops excess; composing schemas must decode with onExcessProperty: 'error'). - Note key/property_name disambiguation is the Phase 3 proof provider's job, not the schema layer. - Note SchemaHash + PropertyIdentityEvidenceSource are foundation for the Phase 3 PropertyWriteCore / proof providers. Refs #775. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…#775 phase 2) Datasource page files can carry compact property descriptors as portable identity hints (VRS R03, R09-R14, T01): - NmdFrontmatterV2 gains optional property_descriptors (shared PropertyDescriptors from notion-effect-schema); absent key omitted on encode, present round-trips intact. - notion-md frontmatter rendering emits descriptors only when datasource parent + schema evidence is available; standalone pages emit none. - Descriptors are identity-only: never freshness, base, outbox, convergence, relation, or settlement state. Unknown descriptor fields fail closed via the strict envelope decode. - Datasource page .nmd remains valid standalone NotionMD. - file-format docs + 13 tests (standalone validity, round-trip, gated emission, fail-closed). Refs #775 #774. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…hase 0) Scope-lock consistency pass: replace a stale non-namespaced telemetry trace (R52/R57-R59/R67-R73) with the namespaced OBS/XC IDs, and add requirement traces to the previously untraced Package Shape, Authority Model, and Resolved Scope Boundaries sections. No competing product contract remained in the per-package VRS; canonical context/ VRS is authoritative. Refs #775. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Problem
PR #775 implemented the v-next
notion-mdsync core, but the long-term scope has grown into the integrated NotionMD + datasource workspace design captured incontext/notion-db-markdown-sync. The PR should now land one coherent system rather than two competing local representations:.nmdpage files for editor workflows, SQLitepagesdata files for tabular/scriptable workflows, hidden.notion/sync-control state, first-class watch/dry-run, and shared property mutation semantics.Goal
Land the full long-term VRS target end-to-end:
track / status / syncNotionMD v-next core..nmdand SQLite files.pages/**/*.nmdas intended user surfaces..notion/state.pagesas the canonical SQL user surface with no publicrowstable/view alias; internal row terminology may exist only as private planner language, not durable user API..nmdproperty descriptors by default as non-authoritative identity hints.@overeng/notion-effect-schemaand a shared property-write core.notion.workspace.v1.json,data/v1/<source>.sqlite,pages/v1/<source>/*.nmd, and.notion/v1/....Completed Foundation
notion-mdv-next public surface:track / status / sync; no publicclone,plan, two-arg sync, or direction flags.source; no missing-source default.source: local | remote.Remaining Work Now In Scope
Phase 0 — VRS And Scope Lock
Dependency: none.
Tasks:
context/notion-db-markdown-sync,packages/@overeng/notion-md/docs/vrs,packages/@overeng/notion-datasource-sync/docs/vrs, andpackages/@overeng/notion-effect-schema/docs.rowuser-surface,_nds_*public-state, and previous replica-contract wording.pagesis the canonical user surface; publicrowsaliases, unversioned layouts, and alternate command paths are not supported.vision.md,requirements.md) stay high-level/testable and that detailed sequencing lives only in PR/issue planning.Acceptance criteria:
Primary file areas:
context/notion-db-markdown-sync/*packages/@overeng/notion-md/docs/vrs/*packages/@overeng/notion-datasource-sync/docs/vrs/**packages/@overeng/notion-effect-schema/docs/*Phase 1 — Shared Property Schema Foundation
Dependency: Phase 0 scope lock.
Tasks:
@overeng/notion-effect-schema: data-source identity, property descriptors, schema/config descriptor hashes, and property identity evidence types.packages/@overeng/notion-effect-schema/src/mod.ts.Acceptance criteria:
Primary file areas:
packages/@overeng/notion-effect-schema/src/properties/*packages/@overeng/notion-effect-schema/src/property-schema.tspackages/@overeng/notion-effect-schema/src/common.tspackages/@overeng/notion-effect-schema/src/mod.tsPhase 2 —
.nmdDescriptor And Standalone ContractDependency: Phase 1 shared schemas.
Tasks:
.nmdfrontmatter decoding to accept default-materialized, non-authoritativeproperty_descriptors..nmdvalidity for datasource page files.Acceptance criteria:
.nmdcan be parsed by standalonenotion-md.Primary file areas:
packages/@overeng/notion-effect-client/src/nmd.tspackages/@overeng/notion-md/src/frontmatter.tspackages/@overeng/notion-md/src/sync.tspackages/@overeng/notion-md/docs/file-format.mdPhase 3 — Shared PropertyWriteCore And Proof Providers
Dependencies: Phases 1-2.
Tasks:
PropertyWriteProofand returns allow/block guard decisions.StandaloneLiveProofProviderfor NotionMD: live schema read, page/property read, descriptor/name/property-id reconciliation, value consistency, and write-class validation.DatasourceWorkspaceProofProviderfor datasource-sync: hidden state, local.nmd/SQLite convergence, relation availability, bases, outbox, conflicts, and settlement context.Acceptance criteria:
source: localstandalone datasource property writes can proceed only with live proof.source: shareddatasource property writes require workspace proof.source: remotelocal property mutation is reported as drift/refused by normal sync.Primary file areas:
packages/@overeng/notion-md/src/sync.tspackages/@overeng/notion-md/src/live.tspackages/@overeng/notion-datasource-sync/src/planner/*packages/@overeng/notion-datasource-sync/src/sync/*Phase 4 — Datasource Workspace User Surface
Dependencies: Phases 0-3.
Tasks:
pages, plus read-onlychanges,conflicts,sync_status,schema, anddebug_*surfaces..notion/v1/state; do not expose alternate public table names or unversioned layouts.notion.workspace.v1.json,data/v1/<source>.sqlite,pages/v1/<source>/*.nmd, and.notion/v1/.pagesandpages/**/*.nmdbefore remote planning.Acceptance criteria:
pagesor.nmdproperties/bodies and get one accepted local intent..notion/v1state is not part of the public data-file contract; public data files expose no_nds_*tables and no publicrowsalias.Primary file areas:
packages/@overeng/notion-datasource-sync/src/replica/replica.tspackages/@overeng/notion-datasource-sync/src/store/*packages/@overeng/notion-datasource-sync/src/local/*packages/@overeng/notion-datasource-sync/src/planner/*packages/@overeng/notion-datasource-sync/src/export/replica-export.tsPhase 5 — CLI, Dry-Run, And Watch Semantics
Dependencies: Phases 3-4.
Tasks:
track --mode local|remote|sharedinnotion.workspace.v1.json; establishedsync,status,export,doctor, and watch commands must not accept per-run mode overrides.sync --watch --dry-runas observe/plan/report loops with suppressed durable effects.local,remote, orshared.track / status / syncas the body/page-file mental model and avoid adding alternate verbs.Acceptance criteria:
sync --modeoverride on established workspaces..notion, object store, outbox, settlement, and Notion write suppression.Primary file areas:
packages/@overeng/notion-md/src/cli-program.tspackages/@overeng/notion-datasource-sync/src/cli/main.tspackages/@overeng/notion-datasource-sync/src/daemon/watch.tsPhase 6 — Non-Body Surfaces And Object Lifecycle
Dependencies: Phases 2, 5.
Tasks:
Acceptance criteria:
Primary file areas:
packages/@overeng/notion-md/src/storage-policy.tspackages/@overeng/notion-md/src/state-store.tspackages/@overeng/notion-md/src/reconcile.tspackages/@overeng/notion-effect-client/src/files.tspackages/@overeng/notion-effect-client/src/comments.tsPhase 7 — Webhook Trigger Integration
Dependencies: Phase 5 watch scheduler.
Tasks:
Acceptance criteria:
Primary file areas:
packages/@overeng/notion-md/src/webhook.tspackages/@overeng/notion-datasource-sync/src/webhook/*Phase 8 — E2E Test Architecture And Verification Matrix
Dependencies: all implementation phases, but test scaffolding can begin after Phase 1.
Tasks:
pagesSQL surface, hidden control-plane isolation, versioned workspace namespace, dry-run suppression, watch guarantees, multi-source workspaces, linked-view projection behavior, relation identity, file/comment/destructive guards, and object GC.Acceptance criteria:
devenv tasks run check:quick --no-tuianddevenv tasks run check:all --no-tuipass before handoff.Primary file areas:
packages/@overeng/notion-md/src/*.test.tspackages/@overeng/notion-md/src/*.e2e.test.tspackages/@overeng/notion-datasource-sync/src/e2e/*packages/@overeng/notion-datasource-sync/src/testing/*packages/@overeng/notion-effect-schema/src/*.unit.test.tsDecisions
notion.workspace.v1.json,data/v1,pages/v1,.notion/v1); unknown or mixed namespaces fail closed.pagesandpages/v1/**/*.nmd; hidden sync state stays under.notion/v1; no publicrows,_nds_*, sidecars, or alternate aliases.track --mode local|remote|sharedestablishes one workspace-wide mode; established commands read it and never accept per-run--mode..nmdare peer user surfaces, but not peer authorities; shared mode converges both locally before remote planning and conflicts on divergent local facts..nmd; property descriptors are optional identity hints, not freshness, base, outbox, convergence, or settlement proof.shared --watchpromises the full durable bidirectional control plane; every write-capable command has true no-write dry-run semantics.Dependency Order
.nmddescriptor file-format support.E2E Test Architecture Proposal
Use a capability-layered matrix instead of one giant live suite:
pagessurface, hidden state isolation, projection rebuild.nmdmaterialization, path claims, object refs, local deletestrack,status,sync, datasource sync commands, JSON output.nmdfilesRule: test each invariant at the cheapest layer that can prove it, and use live Notion only where the API itself is the subject.
Current Verification Baseline
Already completed before the scope expansion:
devenv tasks run check:all --no-tui— passed on the completed v-next sync core.The integrated workspace scope now needs fresh verification after implementation.
References
Closes #774.
Refs #756.
Posted on behalf of @schickling
agent_nameagent_session_idagent_toolagent_tool_versionagent_runtimeagent_modelruntime_profileskills_manifestworktreemachinetooling_profile