Paul M. Jones

Don't listen to the crowd, they say "jump."

The Quakers Tolerated Themselves Out Of Existence

But by 1750, the Quakers were kind of on their way out; by 1750, they were a demographic minority in Pennsylvania, and by 1773 they were a minority in its legislature as well. In 1750 Quakerism was the third-largest religion in the US; by 1820 it was the ninth-largest, and by 1981 it was the sixty-sixth largest. What happened? The Quakers basically tolerated themselves out of existence. They were so welcoming to religious minorities and immigrants that all these groups took up shop in Pennsylvania and ended its status as a uniquely Quaker society. At the same time, the Quakers themselves became more “fanatical” and many dropped out of politics believing it to be too worldly a concern for them; this was obviously fatal to their political domination. The most famous Pennsylvanian statesman of the Revolutionary era, Benjamin Franklin, was not a Quaker at all but a first-generation immigrant from New England. Finally, Quakerism was naturally extra-susceptible to that thing where Christian denominations become indistinguishable from liberal modernity and fade into the secular background.

Source: Book Review of Albion's Seed by Slate Star Codex


Multi-Project Issue Tracking With Producer

With Producer, you can get a list of the open issues from your remote origin by running producer issues from the project repository:

$ cd ~/Code/radarphp/Radar.Adr
$ producer issues
radarphp/Radar.Adr

    14. Separate Package for ResponderAcceptsInterface?
        https://github.com/radarphp/Radar.Adr/issues/14

    29. Service level actions?
        https://github.com/radarphp/Radar.Adr/issues/29

$

However, I’m the lead on about 40 different packages and projects, and at one point or another many of them have issues to be tracked on Github. It’s tedious to go to each package repository to list its issues separately. I want to be able to see a list of all issues on all my projects; then I can review them all at once to see what gets my attention.

To get a list of all open issues on several projects, you can create a bash script that changes to each project directory and runs project issues in each one:

cd ~/Code/atlasphp/Atlas.Cli; producer issues;
cd ~/Code/atlasphp/Atlas.Orm; producer issues;
cd ~/Code/auraphp/Aura.Accept; producer issues;
; ...
cd ~/Code/radarphp/Radar.Project; producer issues;
cd ~/Code/relayphp/Relay.Relay; producer issues;
cd ~/Code/relayphp/Relay.Middleware; producer issues;

Call the script all-issues.sh, make it executable with chmod +x all-issues.sh, and then you can issue ./all-issues.sh to get a list of all open issues on all your projects. Pipe the result to a file for easy viewing if you like!



Producer 2.0.0 Released!

Just a short note to say that most (all?) of the feedback from last month’s inital release of Producer has been incorporated into today’s 2.0.0 stable release!

The major changes are:

  • You are no longer required to install Producer globally. You can now install it as a require-dev in your project and call it as ./vendor/bin/producer. (Personally, I prefer to have it global, but that's mostly because I manage so many different libraries.)

  • Along with that, Producer now recognizes a project-specific .producer/config file so you can override Producer settings on a per-project basis.

  • Finally, Producer does not install phpunit and phpdoc any more. You will need to install them yourself, either globally or as part of your package. The benefit here is that you can now specify custom paths to phpunit and phpdoc commands in your .producer/config file.

(Producer is a command-line quality-assurance tool to validate, and then release, your PHP library package. It supports Git and Mercurial for version control, as well as Github, Gitlab, and Bitbucket for remote origins.)



Empirical Research On Software-Engineering Myths

(Heavily condensed from the original, which you should read in its entirety.)

More Isn’t Always Better: Higher code coverage was not the best measure of post-release failures in the field. If 99 percent of the code has been tested, but the 1 percent that did not get tested is what customers use the most, then there is a clear mismatch between usage and testing. It is more beneficial to achieve higher code coverage of more complex code than to test less complex code at an equivalent level. Those are the kinds of tradeoffs that development managers need to keep in mind.

Write Test Code First: TDD teams produced code that was 60 to 90 percent better in terms of defect density than non-TDD teams. They also discovered that TDD teams took longer to complete their projects--15 to 35 percent longer. “Over a development cycle of 12 months, 35 percent is another four months, which is huge. However, the tradeoff is that you reduce post-release maintenance costs significantly, since code quality is so much better. Again, these are decisions that managers have to make--where should they take the hit?”

Proving the Utility of Assertions: More assertions and code verifications means fewer bugs. Looking behind the straight statistical evidence, they also found a contextual variable: experience. Software engineers who were able to make productive use of assertions in their code base tended to be well-trained and experienced, a factor that contributed to the end results. What kind of action should development managers take based on these findings? The research team believes that enforcing the use of assertions would not work well; rather, there needs to be a culture of using assertions in order to produce the desired results.

Organizational Structure Does Matter – a Lot: Organizational metrics, which are not related to the code, can predict software failure-proneness with a precision and recall of 85 percent. This is a significantly higher precision than traditional metrics such as churn, complexity, or coverage that have been used until now to predict failure-proneness.

Geographical Distance Doesn’t Matter – Much: Most people preferred to talk to someone from their own organization 4,000 miles away rather than someone only five doors down the hall but from a different organization. Organizational cohesiveness played a bigger role than geographical distance.

Source: Exploding Software-Engineering Myths - Microsoft Research


Why Wasn't I Consulted?

(Greatly condensed from the original, which you should read in its entirety; all emphasis in original.)

I like to think about media in terms of questions answered.

Like other media (the web) has a question that it answers better than any other. That question is:

Why wasn't I consulted?

“Why wasn't I consulted,” which I abbreviate as WWIC, is the fundamental question of the web. It is the rule from which other rules are derived. Humans have a fundamental need to be consulted, engaged, to exercise their knowledge (and thus power), and no other medium that came before has been able to tap into that as effectively.

WWIC is the thing people talk about when they talk about nicer-sounding things like “the wisdom of crowds” or “cognitive surplus.” It has become the first thing I think about when I think about the web. I start by asking: “How do we deal with the WWIC problem?” Everything else comes after.

The obvious example of WWIC at work is Wikipedia, created for free by unpaid labor. It tapped into the basic human need to be consulted and never looked back.

Once you see [thumbs-up/thumbs-down icons so that you can rank the comments], a website is complete. You're down to the bedrock. A boolean or integer value is the digital equivalent of a grunt. You can't get any more basic than a like, or a thumbs-up, or a favorite.

Source: The Web Is a Customer Service Medium (Ftrain.com)


PSR-7 and Session Cookies

One of the great things about PHP is its session handling capabilities. One call to session_start() and a huge amount of heavy lifting is done for you. It’s a great aid when writing page scripts.

However, as you start to need finer control over the HTTP response in your project, some of the automatic session behaviors begin to get in the way. In particular, when you are using PSR-7 to build your HTTP response, you realize that session_start() and session_regenerate_id() both automatically do the equivalent of calling setcookie() to write headers directly to the output. This means you cannot buffer those calls into the Response object for later sending.

How then can we use PHP’s session handling, when we want finer control over when and how cookies get sent?

The first trick is to tell PHP not to send a cookie when it does session work. This is accomplished with three ini_set() calls:

ini_set('session.use_trans_sid', false);
ini_set('session.use_cookies', false);
ini_set('session.use_only_cookies', true);

These direct PHP not to use transparent session IDs, not to use cookies, and (counterintuitively) to use only cookies. If I understand correctly, the combination of the last two means that PHP will read only from the cookies, and from nowhere else, to find the session ID value.

With those settings, a call to session_start() will cause PHP to read from the cookie values for the session ID, but it will not cause PHP to set any cookies for the session.

The second trick is to compare the session ID in the incoming request, to the session_id() value at the time you want to send the response. If they are different, that means a session has been started or regenerated, at which point you can send the session cookie manually. The following is an example Relay-compatible middleware that puts session cookie handling logic into effect:

SessionHeadersHandler.php

When you examine the class, note that the cookie-creation code is intended to be the same as in the PHP session handling code itself. Note also that you can extract the relevant logic (“compare the Request session ID to the current one, and send a cookie if they’re different”) and use it in a non-middleware-based application.

With SessionHeadersHandler in place, subsequent middleware decorators can call session_start() and session_regenerate_id(), and PHP will no longer automatically write out a session cookie on its own. The handler will set the cookie into a PSR-7 Response object for later sending.

Unfortunately, this is only a partial solution for session headers. The handler does not deal with things like session cache expire and limiter headers. However, it does give you control over when session cookie itself get sent, and that’s a great aid when you want to work with PSR-7 Response objects.



Rebellion Against The Credentialed Clerics

What we are seeing worldwide, from India to the UK to the US, is the rebellion against the inner circle of no-skin-in-the-game policymaking "clerks" and journalists-insiders, that class of paternalistic semi-intellectual experts with some Ivy league, Oxford-Cambridge, or similar label-driven education who are telling the rest of us 1) what to do, 2) what to eat, 3) how to speak, 4) how to think... and 5) who to vote for.

With psychology papers replicating less than 40%, dietary advice reversing after 30y of fatphobia, macroeconomic analysis working worse than astrology, microeconomic papers wrong 40% of the time, the appointment of Bernanke who was less than clueless of the risks, and pharmaceutical trials replicating only 1/5th of the time, people are perfectly entitled to rely on their own ancestral instinct and listen to their grandmothers with a better track record than these policymaking goons.

Indeed one can see that these academico-bureaucrats wanting to run our lives aren't even rigorous, whether in medical statistics or policymaking. I have shown that most of what Cass-Sunstein-Richard Thaler types call "rational" or "irrational" comes from misunderstanding of probability theory.

Source: Nassim Nicholas Taleb


The Mind of the Left From an Insider

The victim narrative of the Left is very infectious. You are always the victim and you are always owed something. The wealthy are always evil, while you are always good and wholesome. Converts are often more intense than those born into it. My father, raised a leftist, eventually mellowed and began to question some leftist beliefs. My mother, not raised a leftist, but having become one, never mellowed.

The victim narrative was in every conversation.

The class struggle/oppressed victim narrative is part of daily life on the Left. As a child, I would listen to adults talking. With friends and co-workers, with mothers chatting over tea, it was part of every conversation. They would talk about the weather, their kids, television, but before parting, one of them would always say something relating to the greedy oppression of the rich -- and the other had to agree. To not agree was social suicide.

While there were differences between working-class and middle-class leftists, certain attitudes were universal:When a leftist has never worked, they feel very generous toward anyone who claims to need help, who fits the narrative. They are generous with their emotions.

Emphasis in original. Source: The Mind of the Left From an Insider | Frontpage Mag


The Quran's deadly role in inspiring Belgian slaughter

Muhammad's message featured violence with increasing intensity, culminating in surah 9, chronologically the last major chapter of the Quran, and its most expansively violent teaching. Throughout history, Muslim theologians have understood and taught this progression, that the message of the Quran culminates in its ninth chapter.

Surah 9 is a command to disavow all treaties with polytheists and to subjugate Jews and Christians (9.29) so that Islam may “prevail over all religions” (9.33). It is fair to wonder whether any non-Muslims in the world are immune from being attacked, subdued or assimilated under this command. Muslims must fight, according to this final chapter of the Quran, and if they do not, then their faith is called into question and they are counted among the hypocrites (9.44-45). If they do fight, they are promised one of two rewards, either spoils of war or heaven through martyrdom. Allah has made a bargain with the mujahid who obeys: Kill or be killed in battle, and paradise awaits (9.111).

Muslim thought leaders agree that the Quran promotes such violence. Maajid Nawaz, co-founder of the Quilliam Foundation in the United Kingdom, has said, “We Muslims must admit there are challenging Koranic passages that require reinterpretation today. ... Only by rejecting vacuous literalism are we able to condemn, in principle, ISIS-style slavery, beheading, lashing, amputation & other medieval practices forever (all of which are in the Quran). … Reformers either win, and get religion-neutral politics, or lose, and get ISIL-style theocracy.” In other words, Muslims must depart from the literal reading of the Quran in order to create a jihad-free Islamic world.

This is not at all to say that most Muslims are violent. The vast majority of Muslims do not live their lives based on chapter 9 of the Quran or on the books of jihad in the hadith. My point is not to question the faith of such Muslims nor to imply that radical Muslims are the true Muslims. Rather, I simply want to make clear that while ISIL may lure youth through a variety of methods, it radicalizes them primarily by urging them to follow the literal teachings of the Quran and the hadith, interpreted consistently and in light of the violent trajectory of early Islam. As long as the Islamic world focuses on its foundational texts, we will continue to see violent jihadi movements.

Source: The Quran's deadly role in inspiring Belgian slaughter: Column


Producer: Validate and Release PHP Library Packages

tl;dr: Producer will look over your Composer-based library package just before you are ready to tag it for release, make sure it appears ready-to-go, and then do the release for you through Github, Gitlab, or Bitbucket. Producer works with both Git and Mercurial.

I. History

Back when I was working on Solar, we needed a process to package up each release of the entire framework and make sure I hadn’t forgotten anything. Thanks to the magic of the Internet Archive, you can see it here. You can read more about the 10 year old (!!!) process here; the script is of course PEAR-centric, since PEAR was the main packaging system available in PHP at that time.

After Solar was done, we began extracting its individual components as 30 or so separate packages in Aura. As before, I needed a process to make sure each package release was actually ready-to-go, so that earlier PEAR-centric release script evolved into a collection of Composer-centric commands. These release and management tools are specifically for Aura, with its particular conventions and expectations in mind, and have served well for 3 major versions of the project over the last 5+ years.

But now I have started some non-Aura projects: Relay, Radar, Arbiter, Bookdown, and most recently Atlas. These projects do not have the benefit of the automated release process, with all of its checks and validation, that Aura does.

With that in mind, then, I have extracted a substantial amount of the Aura package release process into a new project, Producer, so that I can use it with any non-Aura library package. That means you can use it with your library package, too.

II. Why Use Producer?

When you think your Git or Mercurial library package repository is ready for a tagged version release, Producer help to validate that it is actually in a high-quality releasable state. Then, if Producer thinks everything looks good, it will release your library package through its remote origin API (i.e., through Github, Gitlab, or Bitbucket).

(Note that Producer is not for regular daily development work. It is specifically for the day you want to release the package. At that time, it can be easy to forget steps in a release process; Producer manages those steps for you.)

III. Validating A Package For Release

Most of the things Producer checks for are there because I forgot to check them myself at some point in the past, and it was embarassing for one reason or another.

For example, you don’t want to make a release from a local copy that has not been updated to match the remote copy, or when the local copy has some modified or uncommitted files. So the very first thing Producer does is to pull down changes from the remote origin, push up local changes to the remote, and then check the local status to see if there are uncommitted files. If the local status check fails, Producer won’t release the package.

After it’s sure the local copy is in a clean state, Producer will run composer validate to make sure it has no obvious errors. Obviously, if composer.json is not valid, the package is not in a releasable state.

Next, Producer looks to see if you have a particular set of non-empty informational files in place. These are administrative, but necessary: README, LICENSE, CONTRIBUTING, and CHANGES (not CHANGELOG yet; more on that later). The files may or may not have .md extensions. These files ought to be present in any packaged release, so Producer will fail if they are not present, or if they are empty.

Of course, Producer can’t tell if their contents are sensible or not, though it can tell if the LICENSE notes the current year. If it does not, Producer will tell you to update the copyright year in the LICENSE. You don’t want to release a package with an outdated copyright year!

After that, Producer will run your test suite with PHPUnit. Producer expects that you have a phpunit.xml.dist file at the root of your package, so if that’s missing, the release will fail. Likewise, if the tests fail, Producer will not release the package.

As part of the test-running, Producer will issue composer update to make sure all the require-dev packages are in place. After the tests pass, Producer will check the local copy status yet again, to make sure the tests have cleaned up after themselves properly. This also has the benefit of checking that your “ignore” files are set up properly; at the very least, composer.lock and vendor/ should be ignored, so their presence in the status check will cause Producer to stop its release process.

We want to have well-documented code, so Producer runs PHPDocumentor to check all the docblocks in the package src/ directory. (Yes, this presumes that you have a src/ directory in your library package.) If any PHP docblocks are missing or malformed, Producer will stop the release. Similarly, if the @package tags are missing or incorrect, Producer will tell you which files and stop the release. (In this case, “correct” means “the same as the Composer package name”.)

As the next-to-last step in the validation process, Producer examines your CHANGES file commit timestamp. If the CHANGES file is not part of the very last commit, Producer will balk, and tell you to update your CHANGES so that all changes have been mentioned in the release notes. (Producer uses CHANGES because that’s what I use in Aura; at some point in the future, this may become CHANGELOG, but for now just the release-specific change listing seems enough.)

Finally, Producer will go to your remote origin API and retrieve a list of open issues for the repository. This is not technically a validation step, only a reminder in case there issues you have forgotten to address. If there are open issues, Producer will not stop the release process.

IV. Releasing A Package

The above validations can be run on their own using the producer validate command; they are useful as a pre-flight or pre-check to the actual release process. When the validate command finishes successfully, you can move on to the release command; the release process is exactly the same as the validation process, with the added step of actually releasing the package when validation passes.

At this point, Producer has already looked at your .git or .hg configuration to determine the remote origin API; this can be Github, Gitlab, or Bitbucket. It then prepares and sends a release through that API, using the CHANGES file for the release notes.

Afterwards, it will sync the local copy with the remote origin to pull down any newly-created tags.

That’s it; you’re done! Producer has now run a series of “final checks” on your repository and released it with a new version number.

V. Questions

When I announced Producer over the weekend, it got posted to Reddit by somone other than me (for once ;-). I hope I have answered the “why is Producer useful?” question with this blog post. Two others remain:

  1. Q: “Why does Producer run composer update as part of validation? It should only look at the current state of the repo, not modify the repo.”

    A: Perhaps “validation” is not the right word to use. It’s intended as a pre-flight or preparatory step towards releasing, to make sure that the package will actually install what it requires through Composer. In addition, for my own projects at least, the tests use the Composer autoloader for the src/ files, so composer update is a necessary preliminary to running the tests.

  2. Q: “Why require PHPDocumentor and PHPUnit as part of Producer? What if I have those already installed somewhere else?”

    A: For myself, global installs of these kinds of ecosystem-level tools seem reasonable, but that may be a function of the fact that I mostly manage library packages; having 30+ installs of PHPUnit and PHPDocumentor is just not to my liking. Having said that, I can see how some folks would have different requirements, so I’ll see if I can modify that requirement in a future version of Producer.

Finally, if you have questions/comments/critique, please raise them as issues over at Github. Thanks, and I hope Producer is as useful to you as its earlier versions in Aura have been to me!