Skip to content

Commit 0f4142e

Browse files
authored
feat(ast): harden authoring and CLI generation (#402)
* chore(repo): reconcile fork main with upstream * fix(repo): close promotion review findings
1 parent 544b946 commit 0f4142e

80 files changed

Lines changed: 5604 additions & 431 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/docs.yml‎

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,24 +28,92 @@ env:
2828

2929
jobs:
3030
build:
31-
name: Setup & Install Dependencies
31+
name: Qualify and build authoring documentation
3232
runs-on: ubuntu-latest
33+
outputs:
34+
ready: ${{ steps.qualify.outputs.ready }}
35+
source-sha: ${{ steps.qualify.outputs.source-sha }}
3336
steps:
34-
- name: Checkout
37+
- name: Check out authoring source
3538
uses: actions/checkout@v4
39+
with:
40+
repository: theGeekist/wpkernel-1
41+
ref: main
42+
fetch-depth: 1
43+
persist-credentials: false
44+
45+
- name: Qualify authoring revision
46+
id: qualify
47+
shell: bash
48+
run: |
49+
set -euo pipefail
50+
source_sha="$(git rev-parse HEAD)"
51+
author_name="$(git show -s --format=%an HEAD)"
52+
author_email="$(git show -s --format=%ae HEAD)"
53+
committer_name="$(git show -s --format=%cn HEAD)"
54+
committer_email="$(git show -s --format=%ce HEAD)"
55+
56+
test "${author_name}" = 'Pipe Work'
57+
test "${author_email}" = '780157+pipewrk@users.noreply.github.com'
58+
test "${committer_name}" = 'Pipe Work'
59+
test "${committer_email}" = '780157+pipewrk@users.noreply.github.com'
60+
61+
printf 'source-sha=%s\n' "${source_sha}" >> "${GITHUB_OUTPUT}"
62+
api_url="https://api.github.com/repos/theGeekist/wpkernel-1/actions/workflows/ci.yml/runs?branch=main&event=push&head_sha=${source_sha}&per_page=100"
63+
for attempt in {1..30}; do
64+
ci_state="$(
65+
curl --fail --silent --show-error --location \
66+
--header 'Accept: application/vnd.github+json' \
67+
--header 'X-GitHub-Api-Version: 2022-11-28' \
68+
"${api_url}" |
69+
jq --arg sha "${source_sha}" '
70+
[.workflow_runs[] | select(
71+
.head_sha == $sha and
72+
.head_branch == "main" and
73+
.event == "push"
74+
)] as $runs |
75+
if any($runs[]; .status == "completed" and .conclusion == "success") then
76+
"success"
77+
elif any($runs[]; .status == "completed") then
78+
"failure"
79+
else
80+
"pending"
81+
end'
82+
)"
83+
84+
case "${ci_state}" in
85+
success)
86+
printf 'ready=true\n' >> "${GITHUB_OUTPUT}"
87+
exit 0
88+
;;
89+
failure)
90+
echo "Authoring CI did not pass for ${source_sha}; deployment deferred."
91+
printf 'ready=false\n' >> "${GITHUB_OUTPUT}"
92+
exit 0
93+
;;
94+
esac
95+
96+
sleep 10
97+
done
98+
99+
echo "Authoring CI did not complete for ${source_sha}; deployment deferred."
100+
printf 'ready=false\n' >> "${GITHUB_OUTPUT}"
36101
37102
- name: Setup pnpm
103+
if: steps.qualify.outputs.ready == 'true'
38104
uses: pnpm/action-setup@v4
39105
with:
40106
version: ${{ env.PNPM_VERSION }}
41107

42108
- name: Setup Node.js
109+
if: steps.qualify.outputs.ready == 'true'
43110
uses: actions/setup-node@v4
44111
with:
45112
node-version: ${{ env.NODE_VERSION }}
46113
cache: 'pnpm'
47114

48115
- name: Cache node_modules
116+
if: steps.qualify.outputs.ready == 'true'
49117
id: cache-node-modules
50118
uses: actions/cache@v4
51119
with:
@@ -58,19 +126,19 @@ jobs:
58126
node-modules-${{ runner.os }}-
59127
60128
- name: Install dependencies
61-
if: steps.cache-node-modules.outputs.cache-hit != 'true'
129+
if: steps.qualify.outputs.ready == 'true' && steps.cache-node-modules.outputs.cache-hit != 'true'
62130
run: pnpm install --frozen-lockfile
63131

64132
- name: Setup Pages
133+
if: steps.qualify.outputs.ready == 'true'
65134
uses: actions/configure-pages@v5
66135

67136
- name: Build documentation
137+
if: steps.qualify.outputs.ready == 'true'
68138
run: pnpm docs:build
69139

70-
- name: Format generated docs
71-
run: pnpm format docs/api/@wpkernel/
72-
73140
- name: Upload artifact
141+
if: steps.qualify.outputs.ready == 'true'
74142
uses: actions/upload-pages-artifact@v3
75143
with:
76144
path: docs/.vitepress/dist
@@ -80,6 +148,7 @@ jobs:
80148
name: github-pages
81149
url: ${{ steps.deployment.outputs.page_url }}
82150
needs: build
151+
if: needs.build.outputs.ready == 'true'
83152
runs-on: ubuntu-latest
84153
steps:
85154
- name: Deploy to GitHub Pages

‎.gitignore‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,10 @@ information/
106106
gutenberg/
107107
gutenberg
108108
**/AGENTS.md
109+
!AGENTS.md
109110
docs/internal/*
110111
!docs/internal/php-json-ast/
111-
docs/internal/php-json-ast/*
112-
!docs/internal/php-json-ast/authoring-roadmap.md
112+
!docs/internal/php-json-ast/**
113113
!docs/internal/pipeline/
114114
!docs/internal/pipeline/**
115115
artifacts/

‎.husky/pre-push‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/sh
2+
3+
set -eu
4+
5+
remote_name=${1:-unknown}
6+
remote_url=${2:-unknown}
7+
8+
case "$remote_url" in
9+
https://github.com/theGeekist/wpkernel-1 | https://github.com/theGeekist/wpkernel-1.git | git@github.com:theGeekist/wpkernel-1 | git@github.com:theGeekist/wpkernel-1.git | ssh://git@github.com/theGeekist/wpkernel-1 | ssh://git@github.com/theGeekist/wpkernel-1.git)
10+
exit 0
11+
;;
12+
esac
13+
14+
cat >&2 <<EOF
15+
Push blocked: '${remote_name}' resolves to '${remote_url}'.
16+
Ordinary WPKernel pushes may target only theGeekist/wpkernel-1.
17+
The public wpkernel/wpkernel repository is updated by the publishing workflow.
18+
EOF
19+
exit 1

‎AGENTS.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# WPKernel repository rules
2+
3+
Read the local
4+
[`instructions/wpkernel-repository-guide.md`](instructions/wpkernel-repository-guide.md)
5+
before repository operations or documentation generation.

‎CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616
### Fixed
1717

1818
- **Core package exports** - Fixed missing Vite build entry points for `namespace` and `events` submodules, ensuring `@wpkernel/core/namespace` and `@wpkernel/core/events` imports work correctly at runtime. Updated package.json export paths to match actual build output structure.
19+
- **AST authoring safety** - Authoring descriptors now use private runtime provenance, reject accessor-backed inputs without invoking getters, preserve legal `__proto__` data keys through codec round trips, and prevent untyped props from overriding AST node identity.
20+
- **WordPress mutation generation** - Generated post meta and taxonomy helpers now read values through `WP_REST_Request::get_param()` instead of emitting a non-existent sanitiser function.
21+
- **Generated admin capabilities** - Admin screens and forms now expose create, edit and delete controls only when matching routes exist, preserve taxonomy aliases and intentional empty values, and support configured content and excerpt fields.
22+
- **Pipeline helper registration** - Standard pipelines reject configurations where fragment and builder helper kinds are identical.
1923

2024
### Documentation
2125

2226
- **Import patterns** - Removed outdated namespace import pattern (`import { http } from '@wpkernel/core'`) from README and package documentation. Framework now documents two patterns: submodule imports (recommended for tree-shaking) and flat imports (convenient).
27+
- **Generated API routes** - API generation now emits stable root and package index routes and verifies the rendered `/api/` entry point as part of the documentation build.
2328

2429
### In progress
2530

‎docs/.vitepress/config.ts‎

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export default withMermaid(
128128
logo: '/logo.png',
129129
editLink: {
130130
pattern:
131-
'https://github.com/wpkernel/wpkernel/edit/main/docs/:path',
131+
'https://github.com/theGeekist/wpkernel-1/edit/main/docs/:path',
132132
text: 'Edit this page on GitHub',
133133
},
134134
externalLinkIcon: true,
@@ -304,16 +304,10 @@ export default withMermaid(
304304
collapsed: false,
305305
items: [
306306
{ text: 'Overview', link: '/api/' },
307-
{ text: 'Resources', link: '/api/resources' },
308-
{ text: 'Actions', link: '/api/actions' },
309-
{ text: 'Events', link: '/api/events' },
310-
{ text: 'Jobs', link: '/api/jobs' },
311-
{ text: 'Reporter', link: '/api/reporter' },
312-
{ text: 'Policy', link: '/api/policy' },
313307
],
314308
},
315309
{
316-
text: 'Typedoc output',
310+
text: 'Packages',
317311
collapsed: true,
318312
items: [
319313
{
@@ -328,6 +322,10 @@ export default withMermaid(
328322
text: '@wpkernel/pipeline',
329323
link: '/api/@wpkernel/pipeline/',
330324
},
325+
{
326+
text: '@wpkernel/php-json-ast',
327+
link: '/api/@wpkernel/php-json-ast/',
328+
},
331329
{
332330
text: '@wpkernel/create-wpk',
333331
link: '/api/@wpkernel/create-wpk/',
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# AST task coordination
2+
3+
Architecture version: 1
4+
Task contract version: 1
5+
6+
## Selection
7+
8+
Run the configured task planner before claiming work. A task may start only
9+
when `canStart=true`, its declared dependencies are done, no higher-priority
10+
frontier suppresses it, its write scope is clean apart from its own task brief,
11+
and it does not overlap active work.
12+
13+
The primary checkout is the default. Parallel work in one checkout is expected
14+
when write scopes are disjoint. A dedicated worktree is reserved for work that
15+
is logically disjoint but cannot safely share generated outputs, dependency
16+
state or runtime fixtures.
17+
18+
## Claim and lifecycle
19+
20+
The coordinator owns lifecycle transitions. Workers request them through the
21+
task work log and handoff.
22+
23+
```text
24+
proposed -> ready -> claimed -> in_progress -> review -> done
25+
\-> blocked
26+
proposed | ready | blocked -> cancelled
27+
```
28+
29+
Claiming records owner, owner kind, lease, base SHA, branch and checkout. The
30+
brief above `## Work log` is immutable while claimed. After admission, workers
31+
may update only `base_sha`, `branch`, `worktree` and `updated_at`, plus the work
32+
log and handoff. The coordinator alone changes lifecycle, ownership, lease,
33+
dependencies, decision dependencies, conflicts and `write_scope`.
34+
35+
## Shared-checkout concurrency
36+
37+
- Compare every candidate against all active `write_scope`, `conflicts_with`,
38+
generated outputs and current dirty paths.
39+
- One task owns one source or test path. Globs must describe a cohesive slice,
40+
not reserve a package for convenience.
41+
- `ROADMAP.md`, `STATUS.md`, package manifests, root exports, lockfiles, CI and
42+
generated API documentation are coordinator surfaces unless a task names one
43+
explicitly and runs without an overlapping task.
44+
- A worker does not run repository-wide formatting, dependency installation,
45+
documentation generation, commits, release commands or destructive cleanup.
46+
- Cross-task requests are recorded in the handoff. Do not expand a task into a
47+
concurrent owner’s path.
48+
- Review is a separate ownership pass. The implementer stops editing when the
49+
task enters `review` unless the coordinator reopens it.
50+
51+
The common task brief and `STATUS.md` are deliberately absent from ordinary
52+
implementation write scopes. This avoids turning coordination metadata into a
53+
false global mutex. The coordinator integrates requested lifecycle updates
54+
after checking all active scopes.
55+
56+
## Versioning
57+
58+
- `architecture_version` versions this programme’s architecture decisions.
59+
- Project manifest `schemaVersion` versions planner/workbench configuration.
60+
- Project manifest `taskSchemaVersion` versions the Markdown task-brief shape.
61+
- Planner JSON has its own output `schemaVersion`.
62+
- Versioned contracts use explicit filenames such as
63+
`source-bridge-v1.md`; implementations state the exact contract consumed.
64+
- Generated ownership markers, codec envelopes and migration manifests are
65+
compatibility contracts. A breaking shape requires a new explicit version,
66+
fixtures for both sides of the boundary and a migration decision.
67+
- Package versions, packed artefacts and runtime matrices are evidence. They do
68+
not silently advance an architecture or protocol version.
69+
70+
## Handoff
71+
72+
Every active task records:
73+
74+
```text
75+
Execution mode: shared-checkout | dedicated-worktree
76+
Execution rationale: <why this checkout is safe>
77+
Concurrency evaluation: <active task IDs and overlap result>
78+
Concurrent task scopes: none | <task IDs and disjoint scopes>
79+
Swarm delegation: none | <owner -> delegate: bounded output>
80+
```
81+
82+
The handoff includes changed paths, exact verification commands and results,
83+
behaviour or contract changes, remaining risk and the recommended next task.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# PHP and WordPress JSON AST programme
2+
3+
Architecture version: 1
4+
Task contract version: 1
5+
Project manifest schema: 1
6+
Planner output schema: 1
7+
8+
This directory owns the internal engineering authority for the generic PHP
9+
compiler, WordPress semantic adoption, CLI migration and runtime qualification.
10+
11+
- [`authoring-roadmap.md`](authoring-roadmap.md) preserves the technical
12+
rationale, recovered evidence and original milestone detail.
13+
- [`ROADMAP.md`](ROADMAP.md) groups continuing work and shows dependency
14+
structure. It does not own task state.
15+
- [`STATUS.md`](STATUS.md) is the human-readable task projection.
16+
- [`COORDINATION.md`](COORDINATION.md) defines claims, parallel execution and
17+
integration.
18+
- [`tasks/`](tasks/) contains the authoritative state, dependencies and file
19+
ownership for every executable task.
20+
- [`templates/task.md`](templates/task.md) is the canonical task shape.
21+
22+
The project is consumed through the repository-root
23+
[`task-graph.project.json`](../../../task-graph.project.json). Manifest,
24+
task-brief, plan and architecture versions are independent from package
25+
release versions. Increment each only when its own compatibility contract
26+
changes.

0 commit comments

Comments
 (0)