You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A second, offline validator for the things that are only visible by looking at a project's whole set of declarations at once — which markfluence check cannot see by construction, since its diagnostics are deliberately per-file.
The hole, demonstrated
Two files declaring the same page_idand the same title+space, checked in one invocation:
markfluence update one.md two.md then publishes both to page 12345, the second silently overwriting the first. Nothing in markfluence catches this today, and check had both files in hand when it said "clean" — because a per-file check is the wrong shape for a relation between two files.
What it could check
Offline, in all cases. No credentials, no network — the property that makes check usable anywhere, and the reason anything needing the network belongs elsewhere (see "Out of scope").
Two declarations claiming one title in one space. Confluence enforces title uniqueness per space, so this is a guaranteed failure — and a partial one, since both files pass create's preflight when neither title exists yet and the collision only surfaces once one page has been created. That is exactly the situation S7 (no-partial-create, status Partial) describes, so catching it offline would strengthen a guarantee rather than merely save a round trip.
Files under the root that neither location claims. "Which of my docs aren't published?" is unanswerable today: update skips them, correctly and silently (D7).
Medium:
A parent chain that dangles or cycles across the project, rather than within one invocation. create rejects a cycle among the files it is given (cmd/create/create.go, parent cycle detected among the given files), but a manifest can declare one that no single batch exercises — and a parent naming a path with no metadata anywhere is only caught today if that file happens to be named.
Weak — I would leave these out unless someone asks: orphan pages nothing links to, unreferenced assets under the root, and an entry whose space differs from the project-wide space: (legal, not a defect).
Output should be diagnostics, not a tree
Considered and rejected: rendering the project as a page tree.
Two of the strongest checks are not tree-shaped at all — a duplicate page_id is a relation between two arbitrary nodes, which a tree can only annotate and hope the reader connects, where a line says it outright. The "tree" is also frequently degenerate: a project using parent: <id> for an external page or folder has a forest of roots, and one with no parent: anywhere is a flat list. And check's value is one line per problem plus an exit code; a validator that prints a picture stops being something you put in CI.
markfluence would also then have three tree printers — children for the live tree, #148's local one, and this — which is the "a per-command copy is how two commands come to disagree" problem in output form.
What should be shared is the graph, not the output. The local page graph (every declared page, its parent, whether that parent resolves) is what this needs to find dangles and cycles and what a tree view needs to draw. One internal package, two consumers — the same arrangement as internal/pagemeta and internal/linkindex, for the same reason. A --tree presentation on top of that is then cheap, if it turns out to be wanted.
Naming, and why the timing matters
This would be the second check-* verb, which is the condition that makes renaming check → check-file worth doing: a compound name earns its length when there is something to disambiguate from, and not before. Compound names are already house style here (attachment-list/attachment-upload/attachment-download, noun-first so cobra's alphabetized help groups them).
Worth noting the timing: renaming check touches the --json schema's command enum and checkResult, which is a published contract. markfluence is unreleased, so that is free today and a breaking change after 1.0.0 — so if this lands post-1.0, the rename option has effectively expired and check keeps its name. No milestone set; flagging the constraint rather than deciding it.
Out of scope
Anything requiring the network, which keeps this offline and credential-free:
Entries whose page_id resolves to nothing. Needs a request per page.
A second, offline validator for the things that are only visible by looking at a project's whole set of declarations at once — which
markfluence checkcannot see by construction, since its diagnostics are deliberately per-file.The hole, demonstrated
Two files declaring the same
page_idand the sametitle+space, checked in one invocation:markfluence update one.md two.mdthen publishes both to page 12345, the second silently overwriting the first. Nothing in markfluence catches this today, andcheckhad both files in hand when it said "clean" — because a per-file check is the wrong shape for a relation between two files.What it could check
Offline, in all cases. No credentials, no network — the property that makes
checkusable anywhere, and the reason anything needing the network belongs elsewhere (see "Out of scope").Strong — real hazards with no current diagnostic:
page_id. Silent mutual overwrite, as above. Applies to frontmatter, topages:entries (markfluence.yaml pages: page metadata outside the markdown file #139), and to one of each.titlein onespace. Confluence enforces title uniqueness per space, so this is a guaranteed failure — and a partial one, since both files passcreate's preflight when neither title exists yet and the collision only surfaces once one page has been created. That is exactly the situation S7 (no-partial-create, status Partial) describes, so catching it offline would strengthen a guarantee rather than merely save a round trip.pages:entries naming no file on disk. markfluence.yaml pages: page metadata outside the markdown file #139's D12 makes this deliberately silent — legitimate for a deleted file or a sparse checkout, so not an error — and there is currently no way to ask.updateskips them, correctly and silently (D7).Medium:
parentchain that dangles or cycles across the project, rather than within one invocation.createrejects a cycle among the files it is given (cmd/create/create.go,parent cycle detected among the given files), but a manifest can declare one that no single batch exercises — and aparentnaming a path with no metadata anywhere is only caught today if that file happens to be named.Weak — I would leave these out unless someone asks: orphan pages nothing links to, unreferenced assets under the root, and an entry whose
spacediffers from the project-widespace:(legal, not a defect).Output should be diagnostics, not a tree
Considered and rejected: rendering the project as a page tree.
Two of the strongest checks are not tree-shaped at all — a duplicate
page_idis a relation between two arbitrary nodes, which a tree can only annotate and hope the reader connects, where a line says it outright. The "tree" is also frequently degenerate: a project usingparent: <id>for an external page or folder has a forest of roots, and one with noparent:anywhere is a flat list. Andcheck's value is one line per problem plus an exit code; a validator that prints a picture stops being something you put in CI.markfluence would also then have three tree printers —
childrenfor the live tree, #148's local one, and this — which is the "a per-command copy is how two commands come to disagree" problem in output form.What should be shared is the graph, not the output. The local page graph (every declared page, its parent, whether that parent resolves) is what this needs to find dangles and cycles and what a tree view needs to draw. One internal package, two consumers — the same arrangement as
internal/pagemetaandinternal/linkindex, for the same reason. A--treepresentation on top of that is then cheap, if it turns out to be wanted.Naming, and why the timing matters
This would be the second
check-*verb, which is the condition that makes renamingcheck→check-fileworth doing: a compound name earns its length when there is something to disambiguate from, and not before. Compound names are already house style here (attachment-list/attachment-upload/attachment-download, noun-first so cobra's alphabetized help groups them).Worth noting the timing: renaming
checktouches the--jsonschema'scommandenum andcheckResult, which is a published contract. markfluence is unreleased, so that is free today and a breaking change after 1.0.0 — so if this lands post-1.0, the rename option has effectively expired andcheckkeeps its name. No milestone set; flagging the constraint rather than deciding it.Out of scope
Anything requiring the network, which keeps this offline and credential-free:
page_idresolves to nothing. Needs a request per page.markfluence diff— see that issue.Related
pages:entries. D12 and D7 are where two of these blind spots come from, deliberately.markfluence status/markfluence diff. The tree-view and drift wants live there; this issue is the offline, set-relation half, and the two should share the page graph rather than each build one.markfluence fix. Unrelated except that both are part of working out what markfluence's verbs should be.no-partial-create, Partial) is what check 2 would support.