Port governance, strategy and release engineering from the working copy - #3
Merged
Merged
Conversation
`Wordpressistic/memberistic` carried the product and one CI workflow and nothing else — no contributor guide, no security policy, no release automation, no architecture decisions, no written plan. The personal working copy has all of it, built against this same 2.0.0 baseline. Ported: CLAUDE.md, CONTRIBUTING.md, SECURITY.md, SUPPORT.md, CODE_OF_CONDUCT.md, .editorconfig, CODEOWNERS, issue and PR templates, docs/governance/ and docs/strategy/, and release.yml. No runtime plugin code moves in this commit — the working copy's fixes to class-plugin.php, class-stripe-service.php, class-licensing.php and uninstall.php are each evaluated on their own evidence, with their own tests and their own PR. ADR 0003 records that split and why a wholesale merge was rejected. Release engineering, beyond a straight port: - The copy-and-prune build and the leak-check move to bin/build-dist.sh and bin/assert-dist-clean.sh, so ci.yml's new dist-guard job runs the *same* code the release workflow runs. Inline copies in two workflows drift the first time a dev-only file lands in the root, and then CI reports the archive clean while the release ships it. - The leak-check tests three things independently: that every .distignore entry actually disappeared, that an explicit deny-list is absent whatever .distignore says, and that the files a plugin cannot work without are still present — a pattern greedy enough to ship an empty plugin passes the first two checks. Both failure directions are negative-tested. - docs/README.md no longer ships. It is repository navigation: 20 of its 31 links point into docs/strategy, docs/governance, CLAUDE.md and CONTRIBUTING.md, so in a customer's plugin directory it rendered as a page of dead links. A markdown link check now fails the build on the next one. - The unit suite runs on PHP 8.2/8.3/8.4 rather than 8.3 alone, with the Composer cache keyed per version so one job's vendor/ cannot decide what the other two test. The backlog arrived with 21 acceptance criteria ticked, every one describing files absent from this repository — it would have reported P0-4, P0-5 and P0-6 as largely done here when none has started. All reset to unchecked, with a provenance banner and an inventory of what remains available to port. Added P0-11, which outranks the rest of the page: class-booking-adapter.php ships in 2.0.0 but is missing from Plugin::load_dependencies() and there is no autoloader, so Waiver_Booking_Bridge::register() fatals on init priority 4 on every stock install. Reproduced by loading only what load_dependencies() lists and invoking the init path. Fix follows in its own PR. Verified: php -l clean on 8.4; PHPUnit 47 tests / 831 assertions / 0 failures; node --check clean; both workflows parse as YAML; distributable builds clean and both guards fail correctly when a leak or a missing product file is planted. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LgGmwdEzTdVas4VTDzJQ5m
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Before: this repository carried the product and one CI workflow and nothing else — no contributor guide, no security policy, no release automation, no architecture decisions, no written plan for what comes next. After: all of that is here, ported from the personal working copy (
Shubochandrosarker/memberistic), which was built against this same 2.0.0 baseline.No runtime plugin code moves in this PR. The working copy also contains fixes to
class-plugin.php,class-stripe-service.php,class-licensing.php,uninstall.phpandreadme.txt, plus an integration suite and a plugin directory rename. Each of those is evaluated on its own evidence, with its own tests and its own PR.docs/governance/decisions/0003-controlled-convergence-from-the-working-copy.mdrecords that split and why a wholesale merge was rejected — chiefly that it bundles the directory rename (which makes WordPress treat the upgrade as a different plugin) with a fatal-error fix under one combined justification.Delivers backlog item P0-3 · Release automation.
Type
Rules touched
No runtime code changed. The invariants are unaffected by this PR;
docs/strategy/00-master-plan.mdnow records them in-repo for the first time.Multi-edit checklist
Worth noting: this template's first checklist item — "New class files added to the
require_oncelist inPlugin::load_dependencies()— nothing autoloads" — is precisely the trap that P0-11 below fell into. The template arrives already knowing about it.Documentation
docs/governance/decisions/— ADR 0003CHANGELOG.md— deliberately not touched. Nothing here is user-visible; the distributable's contents change only by removingdocs/README.md, which was dead links.Beyond a straight port
Four things were not copied as-is, because copying them as-is would have been wrong:
1. The build logic is shared, not duplicated. The working copy inlines the copy-and-prune build in
release.yml. Two inline copies in two workflows drift the first time a dev-only file lands in the repository root — and then CI reports the archive clean while the release ships it. Extracted tobin/build-dist.shandbin/assert-dist-clean.sh;ci.yml's newdist-guardjob runs the same two scripts the release runs, on every PR.2. The leak-check tests three things independently, because they fail differently:
.distignoreentry actually disappeared — catches a pattern that silently stopped matching, which still looks fine in a log that prints what it tried to exclude;.distignoresays —docs/strategycarries pricing models and revenue targets and must never reach a customer's plugin directory;Both failure directions are negative-tested (output below).
3.
docs/README.mdno longer ships. It is repository navigation: 20 of its 31 links point intodocs/strategy,docs/governance,CLAUDE.mdandCONTRIBUTING.md, none of which ship. In a customer'swp-content/pluginsdirectory it rendered as a page of dead links. Excluding it fixes that instance; a new markdown link check fails the build on the next one.4. The unit suite runs on PHP 8.2/8.3/8.4 rather than 8.3 alone, with the Composer cache keyed per version — a shared key lets the first job to finish decide what the other two actually test.
Owner-specific references (issue-template links,
CLAUDE.md§ This repository,BRANCHING.md§ upstream) were reoriented: this repository is now described as primary, the working copy as the drafting tree.The backlog arrived overstating its own progress
docs/strategy/09-execution-backlog.mdcame with 21 acceptance criteria ticked, every one describing files that do not exist here —tests/integration/,phpunit-integration.xml,bin/install-wp-tests.sh, theplugin-checkjob. As source of truth it would have reported P0-4, P0-5 and P0-6 as largely finished when none has started.All 21 reset to unchecked, plus a provenance banner and a table of what remains available to port. The rule going forward: a box is ticked only when the evidence is in this repository and its CI is green.
initAdded as P0-11, which outranks everything else on that page.
includes/integrations/class-booking-adapter.phpshipped in 2.0.0 but was never added toPlugin::load_dependencies(), and there is no autoloader. It is the only file underincludes/missing from that list (71 listed, 73 on disk; the other isclass-plugin.php, required by the bootstrap).Waiver_Booking_Bridge::register()callsBooking_Adapter::hook()as its first statement, and is registered oninitpriority 4 whenever the Waiver Manager integration is enabled — whosedefaultis'yes'. The chain fires on a stock install with no configuration:Reproduced by loading only the files
load_dependencies()lists and invoking theinitpath:Neither
php -lnor the unit suite can see this — every file parses perfectly alone, and nothing in the unit suite boots the plugin.Booking_Engine,POS_BridgeandStaff_Dashboardreach the same class.The fix is not in this PR — it is runtime code and gets its own, with a guard test that fails if any file under
includes/is missing from the require list, so the class of bug cannot recur rather than just this instance.What I ran
Guards negative-tested — a guard that never fails is not a guard:
Distributable contents after the change — 2.1 MB tree, 516,647-byte zip:
What I did NOT test
release.ymlend to end. It is tag-triggered and no tag was pushed. Its build and leak-check steps are the same two scripts exercised above, but the version-consistency check, the artifact upload and the draft-release step have not run. Firstv2.0.1tag is the real test.shellcheckon the two new scripts. Not installed in this environment.bash -nparses both. Reported as not-run, not as a pass.Risk and rollback
docs/README.md.release.ymlis tag-triggered and inert until av*tag is pushed;dist-guardis a new job, so reverting simply removes it.Generated by Claude Code