{
  "author": "Joseph Walker",
  "confidence": "provisional",
  "date_created": "2026-09-05",
  "date_modified": "",
  "date_published": "2026-09-05",
  "dek": "Both candidate editors represent the Masters publication contract faithfully and lose nothing in a round trip. Only one produces a pull request automatically — but only the other can hold a credential scoped to a single repository, and the branch protection the first one depends on is not available on this repository at all.",
  "finding_id": "MCG-F-0002",
  "in_ask_corpus": true,
  "kind": "finding",
  "limitations": [
    "This is a bounded desk-and-harness spike, not operating experience. Nothing here was run for a week, by a tired author, on a phone, against a real deadline — which is where authoring tools actually fail.",
    "The round trip exercised each project's serialization module directly rather than through its running application. A defect in the surrounding editor that corrupted a field before serialization would not have been caught.",
    "Confidence is provisional because the deciding evidence is a reading of source code at one version. A capability can be added; the conclusion is about 2.1.8, not about the project's ceiling.",
    "The review assumes a single author who is also the reviewer. A second author would change what 'review' has to mean and could change the answer.",
    "No assessment was made of either project's accessibility, internationalisation, or behaviour on slow connections.",
    "Formatting churn was measured on one 73-line fixture. It is indicative, not a general figure.",
    "The credential comparison is architectural, not empirical. No token of either kind was issued, and no compromise was simulated; the blast-radius figure is a count of repositories the authorizing identity can reach, not a demonstration of harm.",
    "Whether a dedicated single-repository identity is an acceptable containment option depends on GitHub's account terms, which this review notes as a question rather than answers."
  ],
  "methods": [
    "Read the current documentation and source of both projects at pinned versions, and record what each claim came from.",
    "Author three fixture records — a Finding exercising every canonical field, an Essay and a Specimen — valid against the production schema and held outside the compiled content directory.",
    "Express the same contract as a working configuration for each editor, generated from the canonical schema rather than transcribed.",
    "Execute each project's own serialization code path over all three fixtures and re-parse the output with the production compiler, comparing the resulting records field by field.",
    "Read each project's write path directly to establish how an edit actually reaches the repository.",
    "Measure the formatting churn each editor imposes on a hand-written record.",
    "Test the portability question mechanically: delete the editor configuration and confirm the records, compiler and site are unaffected."
  ],
  "negative_results": [
    "Pages CMS 2.1.8 has no pull-request capability. Reading the source at that version, every content write is a direct commit to the branch named in the URL, and no pull-request API call exists anywhere in the codebase. It can create branches, but it cannot open a review.",
    "Neither editor's browser interface was exercised. Every statement about authoring feel, preview behaviour, error feedback or mobile practicality in either product is documentation-derived, and this review is not evidence about any of them.",
    "Schema fidelity failed to separate the candidates. The expectation going in was that a TOML front-matter contract with a nested bibliography would strain at least one of them; both handled it exactly.",
    "Hiding a merge button is not a security boundary. Decap's per-collection publish control removes the UI path to merging, but the OAuth token still carries repository write, so the editor cannot be the thing that enforces review.",
    "Issue #87 cites a repository for Pages CMS that is not the project. The canonical repository is hunvreus/pagescms; the cited one is an unrelated copy with no activity.",
    "Self-hosting Pages CMS would make the editor heavier than the thing it edits: a Next.js application with 65 runtime dependencies, PostgreSQL, a GitHub App and a mailer, against a public site that is static files and a deterministic Python build.",
    "The first pass of this review reached an unconditional recommendation by treating the comparison as one-dimensional. It summarised Decap's authentication as one server-side client secret and did not account for the scope of the token that flow issues, and it named branch protection as the real authority boundary without checking whether the repository can have any. Both were wrong, and the correction changed the conclusion from an approval into a block. A comparison that weighs only the axis a candidate wins is not a comparison.",
    "Decap cannot be configured to request less. Its config schema constrains auth_scope to exactly repo or public_repo, and public_repo cannot reach a private repository, so there is no narrower setting to choose.",
    "The intended enforcement boundary does not exist on this repository. Both the branch-protection and the rulesets endpoints return HTTP 403 with an upgrade prompt, because protected branches on a private repository require a paid GitHub plan."
  ],
  "reconsider_if": [
    "Decap gains a repository-scoped credential path — a GitHub App backend, or an auth_scope narrower than repo. That single change would remove the blocking condition outright and is the improvement that would most change this result.",
    "Pages CMS gains a pull-request write path. It would then hold the credential advantage without the workflow disadvantage, and would likely become the better answer rather than merely a close one.",
    "The repository gains enforceable protection on main — required pull requests, the validation check required, and no bypass available to the editor's principal — at which point the workflow preference can become an authorized pilot.",
    "The repository is made public for reasons of its own, which would enable protection at no cost and reduce the required OAuth scope to public_repo.",
    "A live Decap pilot shows the generated editorial branches or their pull requests are unreadable in practice, or that long-form writing is worse in the browser than in the file.",
    "GitHub branch protection cannot be configured so the validation workflow is a required check, which would remove the only real boundary between the editor and production.",
    "Decap's maintenance stalls, or the community OAuth-handler ecosystem it depends on does.",
    "Masters gains a second author or an external contributor, changing the review model this conclusion assumes.",
    "The canonical schema grows a field shape neither editor can express, which would move the decision back to fidelity."
  ],
  "related_claims": [],
  "related_findings": [
    "MCG-F-0001"
  ],
  "related_sources": [],
  "research_question": "What is the smallest, safest way to author and revise Masters publications from a browser while Git, CI and the deterministic compiler remain the publication authority — and what must be true about credentials and branch authority before such an editor may be switched on?",
  "result": "Both candidates represent the contract faithfully and round-trip every publication kind with no semantic loss, so schema fidelity decides nothing. Two other axes do, and the candidates split them. On workflow authority Decap CMS wins outright: it opens a pull request for every saved draft, while Pages CMS 2.1.8 contains no pull-request code path at all. On credential authority Pages CMS wins: it authenticates as a GitHub App and can hold an installation token scoped to selected repositories, whereas Decap's GitHub backend can request nothing narrower than OAuth 'repo' scope, which GitHub defines as read and write across every repository the authorizing user can reach, including private repositories. The boundary that was supposed to contain that breadth is unavailable: branch protection and rulesets both return 403 on this private personal-account repository. The conclusion is therefore split. Functional preference: Decap. Authorization to run a live pilot: blocked, until a credential and branch-authority containment design is demonstrated.",
  "schema_version": 1,
  "scope": "Two open-source Git-native editors — Decap CMS 3.16.0 and Pages CMS 2.1.8 — assessed against the existing Masters Findings contract on two axes: workflow authority and credential authority. Configuration, authentication and write paths were built and read at pinned versions; each project's own serializer was executed over three real fixture records; the target repository's branch-protection capability was queried directly. No live editing session was performed against either editor, because that requires credentials this review deliberately did not provision. Editors requiring a site framework migration were out of scope.",
  "sources": [
    {
      "accessed": "2026-09-05",
      "note": "Version 3.8.0 resolves the requested OAuth scope as authScope || (openAuthoring ? 'public_repo' : 'repo'), so the private-repository path requests 'repo'.",
      "title": "decap-cms-backend-github — AuthenticationPage.js",
      "url": "https://github.com/decaporg/decap-cms/blob/main/packages/decap-cms-backend-github/src/AuthenticationPage.js"
    },
    {
      "accessed": "2026-09-05",
      "note": "Defines 'repo' as full access to public and private repositories, including read and write access to code, statuses, invitations, collaborators, deployment statuses and webhooks.",
      "title": "GitHub — scopes for OAuth apps",
      "url": "https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps"
    },
    {
      "accessed": "2026-09-05",
      "note": "Protected branches are available in public repositories on Free, and in public and private repositories on Pro, Team, Enterprise Cloud and Enterprise Server.",
      "title": "GitHub — about protected branches",
      "url": "https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches"
    },
    {
      "accessed": "2026-09-05",
      "note": "The endpoint queried against this repository, which answered 403 with an upgrade prompt.",
      "title": "GitHub REST — branch protection",
      "url": "https://docs.github.com/en/rest/branches/branch-protection"
    },
    {
      "accessed": "2026-09-05",
      "note": "Installation access tokens are short-lived and scoped to the repositories the app is installed on — the model Pages CMS uses and Decap's OAuth path has no equivalent for.",
      "title": "GitHub — authenticating as a GitHub App installation",
      "url": "https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/authenticating-as-a-github-app-installation"
    },
    {
      "accessed": "2026-09-05",
      "note": "Consulted because a dedicated single-repository identity is one containment candidate; the account terms govern whether it is acceptable.",
      "title": "GitHub — Terms of Service, account requirements",
      "url": "https://docs.github.com/en/site-policy/github-terms/github-terms-of-service"
    },
    {
      "accessed": "2026-09-05",
      "note": "Collection options including format, filter, publish, delete and identifier_field; the toml-frontmatter format with +++ delimiters.",
      "title": "Decap CMS — configuration options",
      "url": "https://decapcms.org/docs/configuration-options/"
    },
    {
      "accessed": "2026-09-05",
      "note": "Save draft commits to cms/<collection>/<slug> and opens a pull request; approve and publish merges it.",
      "title": "Decap CMS — editorial workflows",
      "url": "https://decapcms.org/docs/editorial-workflows/"
    },
    {
      "accessed": "2026-09-05",
      "note": "All users must have push access to the content repository; GitHub requires a server for authentication.",
      "title": "Decap CMS — GitHub backend",
      "url": "https://decapcms.org/docs/github-backend/"
    },
    {
      "accessed": "2026-09-05",
      "note": "base_url and the /auth and /callback contract an OAuth proxy must implement.",
      "title": "Decap CMS — backends overview",
      "url": "https://decapcms.org/docs/backends-overview/"
    },
    {
      "accessed": "2026-09-05",
      "note": "Community OAuth handlers, including PHP implementations relevant to Masters' existing shared hosting.",
      "title": "Decap CMS — external OAuth clients",
      "url": "https://decapcms.org/docs/external-oauth-clients/"
    },
    {
      "accessed": "2026-09-05",
      "note": "Repeatable groups via nested fields — the control the structured bibliography needs.",
      "title": "Decap CMS — list widget",
      "url": "https://decapcms.org/docs/widgets/list/"
    },
    {
      "accessed": "2026-09-05",
      "note": "date_format and picker_utc, required to store a bare ISO calendar date rather than a timestamp.",
      "title": "Decap CMS — datetime widget",
      "url": "https://decapcms.org/docs/widgets/datetime/"
    },
    {
      "accessed": "2026-09-05",
      "note": "MIT. Source of the format modules used for the round trip; active during the review window.",
      "title": "decaporg/decap-cms",
      "url": "https://github.com/decaporg/decap-cms"
    },
    {
      "accessed": "2026-09-05",
      "note": "MIT, version 2.1.8. Canonical repository; resolves to hunvreus/pagescms. Read for the write path, configuration schema and stored data.",
      "title": "Pages CMS",
      "url": "https://github.com/pages-cms/pages-cms"
    },
    {
      "accessed": "2026-09-05",
      "note": "The hosted operating model offered as the default way to start.",
      "title": "Pages CMS — hosted editor",
      "url": "https://app.pagescms.org"
    },
    {
      "accessed": "2026-09-05",
      "note": "Configuration reference and the environment the self-hosted application expects.",
      "title": "Pages CMS documentation",
      "url": "https://pagescms.org/docs/"
    }
  ],
  "status": "published",
  "superseded_by": "",
  "supersedes": [],
  "systems_evaluated": [
    "Decap CMS 3.16.0",
    "Pages CMS 2.1.8"
  ],
  "title": "A Git-native browser editor for Masters Findings: one candidate wins the workflow, the other wins the credential",
  "topics": [
    "authoring",
    "content management",
    "publication authority",
    "Git-native tooling",
    "build versus reuse"
  ],
  "truth_boundary": "This is a provisional Finding. The result held under the stated method and scope, and has not yet been repeated or tested against a wider sample.",
  "url": "https://mastersconsultinggroup.org/research/findings/git-native-editor-backend-for-masters-findings/",
  "withdrawn_reason": ""
}
