Warning: This code is not very extensively tested and may very well not work in more complicated situations.
The complicated part is getting some code to be placed at the start of a paragraph. This is what \everypar is designed to do, but that gets overwritten and clobbered by so many other things that trying to use it is doomed to failure.
Fortunately, the LaTeX3 team have a package that works around this, which I learnt of from https://tex.stackexchange.com/a/326947/86, and that is l3galley. That answer is from 2016, but I just tried it and it worked fine on your use case.
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\usepackage{tikzpagenodes}
\usepackage{lipsum}
\usepackage{xparse}
\usepackage{l3galley}
\NewDocumentCommand\OutlineParagraph { m }
{
\tikz[overlay,remember picture] \draw
([yshift=\baselineskip]{{pic cs:begin-#1}-|current page text area.west}) --
([yshift=\baselineskip]{{pic cs:begin-#1}-|current page text area.east});
\tikz[overlay,remember picture] \draw
({{pic cs:end-#1}-|current page text area.west}) --
({{pic cs:end-#1}-|current page text area.east});
}
\ExplSyntaxOn
\tl_new:N \g_splicer_saved_tl
\NewDocumentEnvironment{myenv}{ m }
{
\OutlineParagraph{#1}
\group_begin:
\tl_set:Nn \l_splicer_name_tl {#1}
\tl_gset:NV \g_splicer_saved_tl \g_galley_par_begin_hook_tl
\tl_gput_right:Nn \g_galley_par_begin_hook_tl
{
\pgfmark{begin-#1}
}
}
{
\pgfmark{end-\tl_use:N \l_splicer_name_tl}
\tl_gset:NV \g_galley_par_begin_hook_tl \g_splicer_saved_tl
\group_end:
}
\ExplSyntaxOff
\begin{document}
\tikz[overlay,remember picture] \filldraw[red]
(pic cs:begin-nolist) circle(2pt) -- (pic cs:end-nolist) circle(2pt);
\begin{myenv}{nolist}
\lipsum[1]
\end{myenv}
\begin{myenv}{list}
\begin{itemize}
\item \lipsum[1]
\end{itemize}
\end{myenv}
\tikz[overlay,remember picture] \filldraw[blue]
(pic cs:begin-list) circle(2pt) -- (pic cs:end-list) circle(2pt);
\end{document}
This produces:

Now, there are a few snags already with this. You'll notice that I moved the \tikz command that draws the red circles to before the environment. This is because, I'm guessing, the \g_galley_par_begin_hook_tl is executed a few times but only one is actually typeset. This leads to a situation in which there are several tikzmarks that are defined with the same name but only one is written out to the aux file. Before the tikzmark is defined in the document then the one in the aux file wins (which is usually the one you want), but after it has been defined then the one that was last declared wins. I have a workaround for this with \tikzmarknode, but I need to investigate a bit to see what the right way to deal with this is for \tikzmark. For the lines that are drawn at the start and end of the paragraph then this isn't a problem as they are drawn before the tikzmark is defined in the document so they use the definition from the aux file.
Update 2021-03-03
Here's an update. It uses the l3galley code to mark paragraphs inside the environment, and then the tikzmark aliasing facility to pick the first and last of these marks and save them with the given name. (Note: I've updated the aliasing code a little to make aliases available from the outset, just as genuine tikzmarks are; I don't think this is used in this version of the code, though.)
I was running into problems with the actual marking code and where to put it because even with the overlay option then a TikZ picture creates a box and that can cause issues if it occurs in the wrong place, so I've added code that puts it in the footer. To ensure that the right code is executed, I use the tests from the tikzmark package to see if a given tikzmark is on a given page.
\documentclass{article}
%\url{https://tex.stackexchange.com/q/585759/86}
\usepackage{tikz}
\usetikzlibrary{tikzmark}
\usepackage{tikzpagenodes}
\usepackage{lipsum}
\usepackage{xparse}
\usepackage{l3galley}
% These are the commands that will mark the start and end of the paragraphs
\NewDocumentCommand\MarkParagraphStart { O{red} m m }
{%
\tikz[overlay,remember picture] {
\draw[#1]
(
[yshift=#2]
{{pic cs:#3 start}-|current page text area.west}) --
(
[yshift=#2]
{{pic cs:#3 start}-|current page text area.east})
}%
}
\NewDocumentCommand\MarkParagraphEnd { O{blue,dashed,ultra thick} m m }
{%
\tikz[overlay,remember picture] {
\draw[#1]
(
[yshift=#2]
{{pic cs:#3 end}-|current page text area.west}) --
(
[yshift=#2]
{{pic cs:#3 end}-|current page text area.east})
}%
}
\ExplSyntaxOn
% Boolean to control whether we are marking paragraphs
\bool_new:N \g_tikzmark_paragraphs_bool
% Count to keep track of paragraphs
\int_new:N \g_tikzmark_paragraph_count_int
% Installs the hooks to possibly mark the start of paragraphs
\tl_gput_right:Nn \g_galley_par_begin_hook_tl
{
% Are we marking paragraphs?
\bool_if:NT \g_tikzmark_paragraphs_bool
{
% Increment the counter
\int_gincr:N \g_tikzmark_paragraph_count_int
% Mark this place
\pgfmark{paragraph~start~\int_use:N \g_tikzmark_paragraph_count_int}
}
}
% Installs the hooks to possibly mark the end of paragraphs
\tl_gput_right:Nn \g_galley_par_end_hook_tl
{
% Are we marking paragraphs?
\bool_if:NT \g_tikzmark_paragraphs_bool
{
% Mark this place
\pgfmark{paragraph~end~\int_use:N \g_tikzmark_paragraph_count_int}
}
}
% We do the actual drawing in the footer, this prop will contain a list of
% commands to execute. To decide which commands, we associate each one
% with a tikzmark. If the tikzmark is on the current page, the command
% is executed and deleted.
\prop_new:N \g_tikzmark_actions_prop
% This is the command that possibly executes the code
\cs_new:Npn \tikzmark_process_prop:
{
\prop_map_inline:Nn \g_tikzmark_actions_prop
{
\iftikzmarkoncurrentpage{##1}%
##2
\prop_gremove:Nn \g_tikzmark_actions_prop {##1}
\fi
}
}
% Install the processing commands in the footer
\tl_gput_right:cn {@oddfoot}
{
\tikzmark_process_prop:
}
\tl_gput_right:cn {@evenfoot}
{
\tikzmark_process_prop:
}
% The value of \baselineskip needs to be fixed at the invocation time rather
% than execution time. Fortunately, LaTeX3 is adept at handling expansion
% so we wrap the code to install the marks in LaTeX3 functions.
\cs_new:Npn \tikzmark_paragraph_start:nnn #1#2#3
{
\prop_gput:Nnn \g_tikzmark_actions_prop {#1} {
\MarkParagraphStart {#2}{#3}
}
}
\cs_new:Npn \tikzmark_paragraph_end:nnn #1#2#3
{
\prop_gput:Nnn \g_tikzmark_actions_prop {#1} {
\MarkParagraphEnd {#2}{#3}
}
}
\cs_generate_variant:Nn \tikzmark_paragraph_start:nnn {nVn}
% We don't use this command, but it demonstrates how to make a user
% command to draw things using tikzmarks
\NewDocumentCommand \TikzmarkExecute { m m }
{
\prop_gput:Nnn \g_tikzmark_actions_prop {#1} {#2}
}
% Here's the environment to mark paragraphs
\NewDocumentEnvironment{MarkSection}{ m }
{
% Set the boolean for marking the paragraphs
\bool_gset_true:N \g_tikzmark_paragraphs_bool
% Alias the mark at the start of the first paragraph
\tikzmarkalias{#1~start}{paragraph~start~\int_eval:n { \g_tikzmark_paragraph_count_int +1 }}
% Install the code to draw the marks at the start and end
\tikzmark_paragraph_start:nVn {#1~start} \baselineskip {#1}
\tikzmark_paragraph_end:nnn {#1~end} {-2pt} {#1}
}
{
% If we're in horizontal mode when the environment ends then
% we want to exit it to ensure that the end of the last paragraph
% is marked
\ifhmode
\par
\fi
% Stop marking paragraphs
\bool_gset_false:N \g_tikzmark_paragraphs_bool
% Alias the end of the last paragraph
\tikzmarkalias{#1~end}{paragraph~end~\int_use:N \g_tikzmark_paragraph_count_int}
}
\ExplSyntaxOff
\begin{document}
\begin{MarkSection}{no list}
\lipsum[1-4]
\end{MarkSection}
\begin{MarkSection}{list}
\begin{itemize}
\item \lipsum[1]
\item \lipsum[2]
\item \lipsum[3]
\item \lipsum[4]
\end{itemize}
\end{MarkSection}
\end{document}
Here's what this produces:

\pgfmarkinstead? – Andrew Stacey Mar 04 '21 at 00:03\pgfmark, the spurious whitespace is still present, albeit different (a bit more above, a bit less below). – Delfad0r Mar 04 '21 at 00:15