diff --git a/.ai/schedule/SCHEDULE-PLAN.md b/.ai/schedule/SCHEDULE-PLAN.md index 4831e874..60d935a4 100644 --- a/.ai/schedule/SCHEDULE-PLAN.md +++ b/.ai/schedule/SCHEDULE-PLAN.md @@ -43,7 +43,7 @@ Do not use no-op/status-only commits as progress. Do not fabricate runtime, secu ### Deterministic fallback priority -Before a run can become idle or return control while execution capacity remains, scan in this order: accepted open PRs; accepted actionable Issues; CI/test/security/review/audit repairs; authorized dependency maintenance; docs/state/README/coordination and stale lifecycle reconciliation; then non-destructive evidence preparation for an existing blocker. Select the first safe non-conflicting lane automatically. +Before a run can become idle or return control while execution capacity remains, scan in this order: accepted open PRs; accepted actionable Issues; CI/test/security/review/audit repairs; authorized dependency maintenance; **semantic** docs/state/README/coordination and stale lifecycle reconciliation; then non-destructive evidence preparation for an existing blocker. Expected post-merge pointer drift alone must not create a recursive state-only PR. Select the first safe non-conflicting lane automatically. Do not stop early merely to conserve tokens/context. Compact durable state and continue. A host hard limit may interrupt the run, but the next run must resume from the durable checkpoint without requiring a new technical decision from the owner. diff --git a/AGENTS.md b/AGENTS.md index 38d11719..824b8b55 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -66,7 +66,7 @@ Before any voluntary terminal handoff, perform a fresh repository-wide safe-work 2. continue an accepted actionable OPEN Issue that is not blocked by the same external dependency; 3. repair current CI, test, security, review, audit, state-sync or branch-drift failures; 4. perform already-authorized dependency/supply-chain maintenance surfaced by repository evidence or an existing dependency PR; -5. reconcile documentation, compact state, coordination queue, README progress, stale PR/Issue lifecycle, and governance drift; +5. reconcile **semantic** documentation/compact-state/coordination/README/lifecycle/governance drift; expected post-merge pointer drift such as an older `observed_main_sha` is not standalone work; 6. prepare non-destructive evidence, diagnostics, tests or analysis that directly advances an existing authorized blocker without fabricating external evidence. Routine repository maintenance in this ladder is covered by the owner's standing maintenance authority in `.ai/schedule/SCHEDULE-PLAN.md`. It does **not** authorize inventing product features, bypassing a protected action, running an unauthorized Runner task, or creating production/provider/release evidence that does not exist. @@ -398,8 +398,10 @@ Rules: - Large README lifecycle dashboards still change only when public lifecycle truth changes. The compact AI progress block is the exception and is updated on every completed milestone or meaningful durable progress checkpoint. - Before chaining to the next milestone, update compact state and README progress together in the same source commit when source mutation is safe. - Continuous execution must keep the README progress block moving with repository truth; it must not wait for another user prompt merely to publish progress. -- During exact-head certification, do not mutate the candidate source merely to refresh README with pending/terminal CI. Keep README frozen at the certified source baseline, use PR/Issue evidence for live remote status, then synchronize README in the next safe source-changing milestone (for example post-merge reconciliation). -- A missing/stale README progress block is a governance defect and must fail the AI supervisor state audit. +- During exact-head certification, do not mutate the candidate source merely to refresh README with pending/terminal CI. Keep README frozen at the certified source baseline and use PR/Issue evidence for live remote status. +- **Post-merge recursion guard:** do not create a branch/commit/PR whose only purpose is to rewrite `observed_main_sha`, `active_pr`, merge metadata, or equivalent pointer fields after the previous reconciliation PR merged. GitHub live state is authoritative; expected pointer drift is reconciled in memory and folded into the next substantive safe source mutation. +- Semantic progress drift is different: wrong current work, wrong module/progress, wrong blocker/action, or materially stale public status must still be corrected at the next safe substantive source change. +- A missing/stale README progress block relative to the same source state is a governance defect and must fail the AI supervisor state audit. ## User-facing development/status response contract diff --git a/README.md b/README.md index 25e7d78c..4538c93b 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,15 @@ WorkIntel is a single Laravel 13 + React/TypeScript workforce operations platfor ## AI Development Progress - **Repo:** `Vertex-Systems-Network/workforce-intelligence` -- **Current Work:** M14 Windows/Linux trust — provider replies and non-secret target facts pending; dependency PR #140 merged; stale dependency PRs #129–#131 closed +- **Current Work:** PR #144 governance fix is under exact-head certification; third-party Windows trust-signing provider work is deferred by owner and does not block safe repository maintenance. - **Current Module:** M14 — Production Release Trust & Real-Target Readiness - **Module Progress:** [███████░░░] **70%** - **Overall Progress:** [██████████] **100%** — active release-scope modular maturity - **Active Issue:** #62 -- **Active PR:** none -- **Active Branch:** `main` -- **Last Completed:** Dependency PR #140 (Laravel Framework 13.34.0 / League CommonMark 2.10.3, preserving Pint 1.32.1) merged to protected main at 9fca2c4ee028d2011faf9c232296f5984e8ec7c7 after all six exact-head checks passed on d87285a0a11e6089dc2c2b5c1162b55a832ceac4. PRs #129–#131 closed as superseded. M14 evidence remains at 70%. -- **Next Action:** Keep Issue #62 M14 lane WAITING_EXTERNAL until written SSL.com/DigiCert replies or non-secret real-target facts arrive. While it waits, run the mandatory fallback work scan and automatically continue the first safe authorized PR, Issue, CI/test/security/review/audit repair, dependency-maintenance, docs/state/lifecycle reconciliation, or non-destructive blocker-evidence lane. Do not ask the owner to choose routine fallback work and do not voluntarily stop for token/context conservation. Do not deploy, restore, publish, sign, or run Runner tasks without separate authority; Issue #70 remains evidence-gated and Apple remains deferred under Issue #123. +- **Active PR:** #144 +- **Active Branch:** `governance/no-recursive-state-sync` +- **Last Completed:** PR #145 merged to protected main at dfb4fc7ec9536a304b7df582027968dc60f3e53a after all six exact-head checks passed on dab1ad7af440334d6ed7a7847665659216fedb69; zero unresolved review threads. +- **Next Action:** Finish PR #144 exact-head certification and merge only if all required checks pass at the unchanged head. Defer third-party Windows trust-signing provider qualification/integration until future owner authorization; it is not a blocker for safe repository maintenance. Continue the next safe authorized repository lane without buying/configuring signing material or claiming trusted signatures. M14 remains 70% until external evidence gates actually pass; do not deploy, restore, publish or run Runner tasks without separate authority. Issue #70 remains evidence-gated and Apple remains deferred under Issue #123. > Apple/macOS release trust is deferred to future Issue #123 and is not represented as complete. Overall progress is scoped to active release-scope modular maturity. @@ -39,23 +39,24 @@ WorkIntel is a single Laravel 13 + React/TypeScript workforce operations platfor ## Audit snapshot and incomplete tracked work -This continuation index reflects the state observed on **2026-10-08** at protected `main` `9fca2c4ee028d2011faf9c232296f5984e8ec7c7`. GitHub Issues, PRs, `AGENTS.md`, and exact-head checks remain authoritative. +This continuation index reflects the state observed on **2026-10-08** at protected `main` `dfb4fc7ec9536a304b7df582027968dc60f3e53a`. GitHub Issues, PRs, `AGENTS.md`, and exact-head checks remain authoritative. | Priority | Work item | Current state | Completion condition | |---|---|---|---| -| P0 | M14 external release configuration — Issue #62 | No SSL.com/DigiCert reply was found after 2026-09-27; provider qualification and non-secret real-target facts remain pending. This does not authorize production, publication, signing, restore, or Runner execution. | Record written provider/admin and real-target evidence under Issue #62 while preserving separate production and Runner authority boundaries. | +| P0 | M14 external release configuration — Issue #62 | Owner deferred third-party Windows trusted-signing provider qualification/integration until future authorization. GitHub `agent-v*` tag ruleset and its VERIFIED attestation are confirmed; `production-release`/immutable-release and real-target evidence remain unverified. No trusted signature is claimed. | Record remaining authorized administrator/target evidence under Issue #62 while preserving separate signing, publication, production, restore, and Runner authority boundaries. | | P1 | Intermittent seed failure — Issue #70 | Root cause remains unproven. Existing diagnostics preserve failure evidence; Runner RB-005 remains blocked/not authorized. | Capture a future recurrence or prove a deterministic cause, then make a focused fail-closed repair with exact-head certification. | | Deferred | Apple release trust — Issue #123 | Deferred pending owner authorization and required Apple subscription/tooling. | Resume only with explicit authorization and required credentials/tooling. | | Completed | Dependency PR #139 | React DOM/types 19.3.0 merged to protected main at `d38034c0ebc05460bf68581e01140801966d714f`. | Complete. | | Completed | Dependency PR #140 | Laravel Framework 13.34.0 / CommonMark 2.10.3, preserving Pint 1.32.1; merged at `9fca2c4ee028d2011faf9c232296f5984e8ec7c7`. Six exact-head checks passed on `d87285a0a11e6089dc2c2b5c1162b55a832ceac4`; diff was `composer.lock` only. | Complete. | +| Completed | Governance PR #143 | Continuous no-idle fallback execution merged at `9e6e95082fd8bc5511dc5502a3e3259203667356`; exact-head Code Quality, Linux CI, and Windows Certification passed on `14709d071048725ff6e065b9422d26c514b17326`. | Complete. | | Closed | Dependency PRs #129–#131 | Closed as superseded by merged PR #140, which carries the selected current dependency versions. | Complete. | | Completed | Dependency PR #76 | Laravel Pint 1.32.1 merged to protected main before this snapshot. | Complete. | | Completed | Dependency PR #137 | Gridstack 13.3.0 and matching drag/drop test merged to protected main at `ce4d13affcf0b0d13a668c19c96db102aae47119`. | Complete. | ### Continuation order -1. PR #140 is merged and PRs #129–#131 are closed as superseded. -2. Resume Issue #62 external-evidence work when provider responses or non-secret target facts arrive; do not enter production or Runner lanes without separate authority. +1. Continuous fallback governance from PR #143 is merged; pointer-only post-merge state drift must not create recursive sync PRs. +2. While Issue #62 is externally waiting, run the mandatory fallback scan and automatically continue safe authorized maintenance/development work. 3. Keep Issue #70 open until evidence proves a root cause and focused fix; RB-005 remains not-authorized. 4. Apple release trust remains deferred under Issue #123. @@ -86,7 +87,7 @@ The table below is the repository-level roadmap view. `Progress` represents acce | M11 | Role UX + Help + Onboarding | Complete | `██████████` 100% | 2026-08-20* | 2026-08-21* | Localized guidance/onboarding/RTL contracts complete | | M12 | Accessibility, Performance & Final Certification | Complete — active-scope closure | `██████████` 100% | 2026-08-21 | 2026-08-22 | Hosted + Windows certification accepted; withdrawn Laragon gate is not represented as passed | | M13 | Agent Lifecycle Reliability — Batches 1–6 | Complete | `██████████` 100% | 2026-08-22 | 2026-08-24 | Managed update, deterministic packaging, immutability, transactional publication, browser version authority and runtime-bound deployment accepted | -| M14 | Production Release Trust & Real-Target Readiness | **VERIFYING / PARTIALLY COMPLETE** | `███████░░░` **70%** | 2026-08-31 | **Active** | Active scope: Windows/Linux trust, publication and real-target/recovery. Apple/macOS trust is deferred to future Issue #123 and is not claimed complete | +| M14 | Production Release Trust & Real-Target Readiness | **VERIFYING / PARTIALLY COMPLETE** | `███████░░░` **70%** | 2026-08-31 | **Active** | GitHub release-control and real-target/recovery evidence remain separate gates. Third-party Windows signing and Apple/macOS trust are deferred; no trusted signature or publication is claimed | \* The canonical M0–M12 maturity record stores per-phase completion state but not precise per-phase start/end timestamps. M0–M11 therefore use the repository's initial implementation/certification evidence window instead of inventing unsupported day-level precision. M12, M13 and M14 dates are tied to explicit repository/PR authority and closure records. diff --git a/docs/ai-state/COORDINATION-QUEUE.yaml b/docs/ai-state/COORDINATION-QUEUE.yaml index e59064fc..372103b0 100644 --- a/docs/ai-state/COORDINATION-QUEUE.yaml +++ b/docs/ai-state/COORDINATION-QUEUE.yaml @@ -2,14 +2,14 @@ "schema_version": 1, "non_authoritative_resume_index": true, "repository": "Vertex-Systems-Network/workforce-intelligence", - "observed_main_sha": "9fca2c4ee028d2011faf9c232296f5984e8ec7c7", + "observed_main_sha": "dfb4fc7ec9536a304b7df582027968dc60f3e53a", "reconciled_at": "2026-10-08", "issues": [ { "number": 62, "title": "M14 external release configuration — immutable tags and production-release gate", "state": "open", - "action": "await-provider-replies-and-nonsecret-target-facts-no-production-or-runner-authority" + "action": "owner-deferred-provider-signing;gate-a-a2-verified;remaining-admin-target-evidence-open" }, { "number": 70, @@ -25,6 +25,36 @@ } ], "pull_requests": [ + { + "number": 144, + "title": "governance: prevent recursive state-only reconciliation loops", + "state": "open", + "draft": false, + "head_ref": "governance/no-recursive-state-sync", + "action": "owner-defers-provider-signing; exact-head-certification-pending" + }, + { + "number": 145, + "title": "ci: supervise Laravel server during Windows browser certification", + "state": "merged", + "draft": false, + "head_sha": "dab1ad7af440334d6ed7a7847665659216fedb69", + "base_sha": "9e6e95082fd8bc5511dc5502a3e3259203667356", + "head_ref": "ci/windows-e2e-server-supervisor-2026-10-08", + "action": "completed-all-six-exact-head-checks-green", + "resulting_main_sha": "dfb4fc7ec9536a304b7df582027968dc60f3e53a" + }, + { + "number": 143, + "title": "governance: enforce no-idle fallback execution and reconcile state", + "state": "merged", + "draft": false, + "head_sha": "14709d071048725ff6e065b9422d26c514b17326", + "base_sha": "9fca2c4ee028d2011faf9c232296f5984e8ec7c7", + "head_ref": "docs/post-pr140-state-sync-20261008", + "action": "completed-no-idle-fallback-governance", + "resulting_main_sha": "9e6e95082fd8bc5511dc5502a3e3259203667356" + }, { "number": 129, "title": "chore(deps): bump laravel/framework from 13.29.0 to 13.33.0", diff --git a/docs/ai-state/CURRENT-STATE.yaml b/docs/ai-state/CURRENT-STATE.yaml index 08ea3dc3..90a23b58 100644 --- a/docs/ai-state/CURRENT-STATE.yaml +++ b/docs/ai-state/CURRENT-STATE.yaml @@ -2,14 +2,14 @@ "schema_version": 1, "compact_state_path": "docs/ai-state", "repository": "Vertex-Systems-Network/workforce-intelligence", - "observed_main_sha": "9fca2c4ee028d2011faf9c232296f5984e8ec7c7", + "observed_main_sha": "dfb4fc7ec9536a304b7df582027968dc60f3e53a", "active_issue": 62, - "active_pr": null, - "active_branch": "main", - "current_milestone": "M14 Windows/Linux release trust — real-target/recovery evidence prepared", + "active_pr": 144, + "active_branch": "governance/no-recursive-state-sync", + "current_milestone": "M14 Windows/Linux release trust — provider-based signing deferred; real-target evidence remains separate", "milestone_status": "WAITING_EXTERNAL", - "last_completed_milestone": "Dependency PR #140 (Laravel Framework 13.34.0 / League CommonMark 2.10.3, preserving Pint 1.32.1) merged to protected main at 9fca2c4ee028d2011faf9c232296f5984e8ec7c7 after all six exact-head checks passed on d87285a0a11e6089dc2c2b5c1162b55a832ceac4. PRs #129–#131 closed as superseded. M14 evidence remains at 70%.", - "exact_next_safe_action": "Keep Issue #62 M14 lane WAITING_EXTERNAL until written SSL.com/DigiCert replies or non-secret real-target facts arrive. While it waits, run the mandatory fallback work scan and automatically continue the first safe authorized PR, Issue, CI/test/security/review/audit repair, dependency-maintenance, docs/state/lifecycle reconciliation, or non-destructive blocker-evidence lane. Do not ask the owner to choose routine fallback work and do not voluntarily stop for token/context conservation. Do not deploy, restore, publish, sign, or run Runner tasks without separate authority; Issue #70 remains evidence-gated and Apple remains deferred under Issue #123.", + "last_completed_milestone": "PR #145 merged to protected main at dfb4fc7ec9536a304b7df582027968dc60f3e53a after all six exact-head checks passed on dab1ad7af440334d6ed7a7847665659216fedb69; zero unresolved review threads.", + "exact_next_safe_action": "Finish PR #144 exact-head certification and merge only if all required checks pass at the unchanged head. Defer third-party Windows trust-signing provider qualification/integration until future owner authorization; it is not a blocker for safe repository maintenance. Continue the next safe authorized repository lane without buying/configuring signing material or claiming trusted signatures. M14 remains 70% until external evidence gates actually pass; do not deploy, restore, publish or run Runner tasks without separate authority. Issue #70 remains evidence-gated and Apple remains deferred under Issue #123.", "pending_runner_ids": [ "RB-001", "RB-002", @@ -23,10 +23,10 @@ "RB-005" ], "current_blockers": [ - "Written confirmation from SSL.com and/or DigiCert is pending after qualification inquiries were sent on 2026-09-26; Pakistan legal-entity eligibility, exact public Code Signing product eligibility, GitHub-hosted CI support, HSM custody, headless authentication, RFC3161 timestamping, signer fingerprint verification, audit logging, credential rotation/revocation, pricing and onboarding remain unconfirmed.", - "No Windows public-trust provider has been selected; provider-specific remote-HSM signing integration and readiness evidence cannot be finalized yet.", + "Third-party Windows trust-signing provider qualification/integration is deferred by owner on 2026-10-08 until future authorization; provider replies are not a blocker for current safe repository maintenance.", + "No Windows public-trust provider has been selected; do not build provider-specific signing integration, configure signing secrets, or claim trusted signatures while this lane is deferred.", "Public-trust Windows private signing keys must not be treated as portable GitHub PFX secrets; existing PFX secrets remain unset for the public-trust path.", - "Administrator-bypass posture, main=branch policy type, agent-v*=tag policy type, and release-policy-token least privilege remain administrator-attested where GitHub read APIs do not prove them directly.", + "Live GitHub readback on 2026-10-08 confirms active main branch ruleset 21176050 with zero bypass actors and active `agent-v-release-tags` ruleset 23938765 for `refs/tags/agent-v*` with zero bypass actors plus update/deletion restrictions; the VERIFIED attestation matches updated_at `2026-09-24T17:49:27.650+05:00`. `production-release` environment protection, token placement/least privilege, and immutable-releases setting remain Not Verified because the connector cannot read those admin endpoints.", "Issue #70 remains open; RB-005 remains not-authorized/blocked.", "Apple/macOS signing and notarization are intentionally deferred to future Issue #123 and are not an active M14 execution blocker; do not claim Apple completion." ], @@ -47,11 +47,11 @@ "last_reconciled_at": "2026-10-08", "response_status": { "repository_name": "Vertex-Systems-Network/workforce-intelligence", - "current_work": "M14 Windows/Linux trust — provider replies and non-secret target facts pending; dependency PR #140 merged; stale dependency PRs #129–#131 closed", + "current_work": "PR #144 governance fix is under exact-head certification; third-party Windows trust-signing provider work is deferred by owner and does not block safe repository maintenance.", "current_module": "M14 — Production Release Trust & Real-Target Readiness", "module_progress": { "percent": 70, - "basis": "Apple/macOS remains deferred to Issue #123. Windows/Linux real-target and recovery evidence is now source-prepared, but no live target, restore, signing, publication, or provider qualification evidence has executed; M14 remains 70%." + "basis": "Third-party provider-based trusted signing is deferred by owner for future scope. No provider, signing, publication or real-target evidence is claimed; M14 remains 70% until its authorized evidence gates pass." }, "overall_progress": { "percent": 100, @@ -74,6 +74,14 @@ "docs_compact_state_readme_coordination_lifecycle_reconciliation", "non_destructive_evidence_diagnostics_for_existing_blocker" ], - "may_invent_product_scope": false + "may_invent_product_scope": false, + "state_pointer_only_drift_is_actionable": false + }, + "state_sync_policy": { + "observed_main_sha_is_resume_anchor_not_live_authority": true, + "recursive_post_merge_state_only_pr_forbidden": true, + "pointer_only_drift_reconciled_in_memory": true, + "semantic_status_drift_requires_source_sync": true, + "merge_evidence_may_live_on_pr_issue_until_next_substantive_mutation": true } } diff --git a/docs/ai-state/DETERMINISTIC-CLAIMS.yaml b/docs/ai-state/DETERMINISTIC-CLAIMS.yaml index 67145189..e270b606 100644 --- a/docs/ai-state/DETERMINISTIC-CLAIMS.yaml +++ b/docs/ai-state/DETERMINISTIC-CLAIMS.yaml @@ -121,6 +121,24 @@ "subject": "safe_fallback_is_selected_automatically_without_user_choice", "value": true, "authority": "docs/ai-state/FAST-BATCH-EXECUTION.md#external-waits-and-blocked-lanes" + }, + { + "id": "CLAIM-021", + "subject": "recursive_post_merge_state_only_pr_allowed", + "value": false, + "authority": "AGENTS.md#readme-progress-synchronization-contract" + }, + { + "id": "CLAIM-022", + "subject": "observed_main_sha_pointer_drift_is_standalone_fallback_work", + "value": false, + "authority": "AGENTS.md#mandatory-fallback-work-scan--no-idle" + }, + { + "id": "CLAIM-023", + "subject": "semantic_status_drift_requires_source_sync", + "value": true, + "authority": "AGENTS.md#readme-progress-synchronization-contract" } ] } diff --git a/docs/ai-state/EXECUTION-JOURNAL.md b/docs/ai-state/EXECUTION-JOURNAL.md index 6521ab33..405f8c46 100644 --- a/docs/ai-state/EXECUTION-JOURNAL.md +++ b/docs/ai-state/EXECUTION-JOURNAL.md @@ -1,3 +1,11 @@ +## 2026-10-08 — post-merge state recursion guard + +- Verified PR #143 merged to protected main at `9e6e95082fd8bc5511dc5502a3e3259203667356` after exact-head Code Quality, Linux CI and Windows Certification passed on `14709d071048725ff6e065b9422d26c514b17326`. +- Identified a recursive-maintenance risk: updating only `observed_main_sha`/merge pointers after a reconciliation PR would create another merge, immediately stale the pointer again, and make fallback selection loop on state-only PRs. +- Added a fail-safe recursion guard: pointer-only post-merge drift is reconciled in memory and folded into the next substantive source mutation; it is not standalone fallback work. +- Semantic README/state drift remains actionable and must still be corrected. +- M14 remains 70% and WAITING_EXTERNAL as one lane; fallback execution continues independently under existing authority. + ## 2026-10-08 — continuous fallback execution hardening - Root cause: durable next-action state could still tell the supervisor to wait on M14, allowing a valid external wait to dominate the whole workspace despite continuous Fast-Batch policy. @@ -279,3 +287,19 @@ Older detail through 2026-09-22 is archived at `docs/ai-state/archive/EXECUTION- - Closed PRs #129, #130, and #131 as superseded by #140; each received a rationale comment. - M14 remains `WAITING_EXTERNAL` at 70%; dependency maintenance does not advance release-trust evidence. Issue #62 provider/target facts remain pending, Issue #70 root cause remains unproven and RB-005 unauthorized, and Apple remains deferred under Issue #123. - No product source, production deployment, migration, restore, signing, publication, provider purchase, or Runner task changed or ran. + + +## 2026-10-08 — PR #145 merge and PR #144 current-main certification + +- Verified PR #145 exact head `dab1ad7af440334d6ed7a7847665659216fedb69`: `governance`, `CodeQL`, `windows-certification`, Laravel Pint changed-PHP quality, CodeQL JS/TS quality and `test` all passed; zero unresolved review threads. +- Merged PR #145 to protected main at `dfb4fc7ec9536a304b7df582027968dc60f3e53a`. The change adds bounded recovery supervision for the Laravel E2E server after PR #144's Windows certification hit connection refusals during browser accessibility coverage. +- PR #144 was behind after the merge. Its existing changes touched 11 files, while main's only commit beyond its base changed `tools/e2e-server-supervisor.mjs` and `tools/playwright.config.mjs`; those paths do not overlap. The PR branch was rebased onto the exact current main while preserving its accepted governance changes. +- PR #144 exact-head checks must pass before merge. M14 remains 70% WAITING_EXTERNAL; no production deployment, migration, restore, signing, publication, provider purchase or Runner task occurred. + + +## 2026-10-08 — owner defers third-party Windows trust signing + +- Owner directed that trusted digital signing via SSL.com/DigiCert or another third-party provider is not required in the current scope and may be added in the future. +- Provider qualification/integration is recorded as deferred until future owner authorization. Do not purchase or configure signing material or claim trusted signatures. This does not block unrelated safe repository maintenance. +- M14 remains 70%; deferred signing is not represented as complete. Production, restore, publication and Runner authority remain separate. +- PR #144's first current-main certification test on head `4701c1d42502a2847f377a2304c440fbb1a49c60` failed because README wrapped SHAs in backticks while the progress-state contract requires exact text. Removed those backticks on head `3ad2962fe8d88bd9e170e86a896ed9d1bec21221`; the next exact-head checks are not yet visible. diff --git a/docs/ai-state/FAST-BATCH-EXECUTION.md b/docs/ai-state/FAST-BATCH-EXECUTION.md index c1aa4207..238e2e9a 100644 --- a/docs/ai-state/FAST-BATCH-EXECUTION.md +++ b/docs/ai-state/FAST-BATCH-EXECUTION.md @@ -51,7 +51,7 @@ Before any voluntary handoff, run the mandatory fallback scan: 2. accepted actionable OPEN Issue; 3. CI/test/security/review/audit/state/branch repair; 4. authorized dependency and supply-chain maintenance; -5. docs/compact-state/README/coordination/PR-Issue lifecycle reconciliation; +5. semantic docs/compact-state/README/coordination/PR-Issue lifecycle reconciliation; pointer-only post-merge drift is not standalone work; 6. non-destructive evidence or diagnostic preparation for an existing authorized blocker. The owner standing maintenance authority recorded in `.ai/schedule/SCHEDULE-PLAN.md` covers routine repository maintenance in this ladder. It never creates product scope or protected production/provider/release/migration authority. @@ -76,7 +76,7 @@ User input remains required only for information or authority the repository can At every completed milestone and meaningful durable progress checkpoint, synchronize `docs/ai-state/CURRENT-STATE.yaml` and the root `README.md` **AI Development Progress** block before chaining onward, when source mutation is safe. -Do not invent percentages. Preserve the exact-head rule: while a candidate head is under certification, do not mutate it solely for status; record live remote status on the PR/Issue evidence surface and synchronize README at the next safe source-changing checkpoint. +Do not invent percentages. Preserve the exact-head rule: while a candidate head is under certification, do not mutate it solely for status; record live remote status on the PR/Issue evidence surface. After merge, expected pointer-only drift (`observed_main_sha`, active PR identity, merge metadata) must not spawn a recursive state-only PR; fold it into the next substantive safe source mutation. Semantic status drift still requires correction. ## User updates diff --git a/docs/ai-state/LAST-CHECKPOINT.md b/docs/ai-state/LAST-CHECKPOINT.md index cb3eeaad..2999de72 100644 --- a/docs/ai-state/LAST-CHECKPOINT.md +++ b/docs/ai-state/LAST-CHECKPOINT.md @@ -1,20 +1,26 @@ # Last AI Engineering Supervisor Checkpoint **Repository:** `Vertex-Systems-Network/workforce-intelligence` -**Observed protected main:** `9fca2c4ee028d2011faf9c232296f5984e8ec7c7` +**Observed protected main:** `dfb4fc7ec9536a304b7df582027968dc60f3e53a` **Active Issue:** #62 **Deferred Future Issue:** #123 — Apple signing, notarization and macOS release trust -**Active PR:** none for M14 source implementation -**Active branch:** `main` -**Milestone:** M14 Windows/Linux release trust — real-target/recovery evidence prepared -**Status:** WAITING_EXTERNAL for M14; dependency maintenance checks run independently. +**Active PR:** #144 — governance/no-recursive-state-sync +**Active branch:** `governance/no-recursive-state-sync` +**Milestone:** M14 Windows/Linux release trust — provider-based signing deferred; real-target evidence remains separate +**Status:** PR #144 exact-head certification pending; provider-based Windows trust signing deferred by owner; M14 remains 70%. ## Completed +- Owner decision on 2026-10-08: defer third-party Windows trust-signing provider qualification/integration to future scope. Do not purchase/configure signing material or claim trusted signatures; this does not block safe repository maintenance. +- PR #145 merged to protected main at `dfb4fc7ec9536a304b7df582027968dc60f3e53a` after all six exact-head checks passed on `dab1ad7af440334d6ed7a7847665659216fedb69`; it adds bounded supervision/recovery for the Laravel E2E server. Zero unresolved review threads. + + +- PR #143 merged to protected main at `9e6e95082fd8bc5511dc5502a3e3259203667356` after exact-head Code Quality, Linux CI and Windows Certification passed; continuous no-idle fallback execution is integrated. - Dependency PR #76 merged to protected main at `2e623b4e22111a88a42fd749dbe24f5de6fe0a9f`. - Dependency PR #137 merged at `ce4d13affcf0b0d13a668c19c96db102aae47119`; Gridstack 13.3.0 and its matching regression test are integrated. - M14 remains 70%; dependency maintenance does not advance M14 evidence progress. -- Issue #62 was checked on 2026-10-08; no SSL.com or DigiCert inbound reply since 2026-09-27. Provider qualification and non-secret real-target facts remain pending. +- Owner directed on 2026-10-08 that third-party Windows trusted-signing provider qualification/integration be deferred to future authorization. Issue #62's GitHub release-control/admin evidence and non-secret target facts remain separate external gates; no signature/publication evidence is claimed. +- Read-only GitHub API reconciliation verified Gate A/A2 on 2026-10-08: active `agent-v-release-tags` ruleset 23938765 has zero bypass actors and update/deletion restrictions, and the protected-main attestation is VERIFIED for exact `updated_at` `2026-09-24T17:49:27.650+05:00`. `production-release`, immutable-releases, and target evidence remain Not Verified. - Apple/macOS trust remains deferred to Issue #123. Issue #70 remains open with its root cause unproven and RB-005 blocked/not-authorized. - No production deployment, migration, traffic mutation, restore, signing, publication, provider purchase or RB-005 execution occurred. @@ -24,15 +30,12 @@ - PRs #129–#131 are closed as superseded by #140; protected-main lockfile versions are Laravel Framework 13.34.0, League CommonMark 2.10.3, and Laravel Pint 1.32.1. - PR #141 — README/AI-state reconciliation after PR #139 — merged at `46381d7752f914e5d70f6a71bd125a887ba0f6f7`; PR #142 then advanced main with the Playwright `--no-reload` fix to `569c633cb297771717864703635eaefa6245d732`. -## Active M14 critical chain +## Active M14 evidence lanes -1. Written SSL.com/DigiCert Windows provider qualification. -2. Qualified Windows provider selection + provider-specific remote-HSM integration. -3. Real Windows signing authority + readiness. -4. Actual Windows signing/RFC3161 + Linux provenance. -5. Authorized immutable trusted publication. -6. Execute the prepared real-target + isolated backup-to-restore evidence plan. +1. Gate A/A2 are verified. Continue only the already-authorized remaining GitHub release-control evidence lane in Issue #62; `production-release` protection, immutable-releases, and non-secret target facts remain Not Verified. +2. Keep non-secret real-target and recovery evidence separate and do not execute target, restore, signing, publication or Runner tasks without their required authority. +3. Third-party Windows trusted signing and Apple/macOS signing are deferred to future owner authorization; do not purchase/configure signing material or claim trusted signatures. ## Next Action -Keep Issue #62 M14 lane WAITING_EXTERNAL until written SSL.com/DigiCert replies or non-secret real-target facts arrive. While M14 waits, run the mandatory fallback scan and automatically continue the first safe authorized maintenance/development lane. Routine fallback selection must not require owner confirmation and must not stop early for token/context conservation. Preserve separate authority for production, restore, signing, publication, migrations, provider credentials and Runner execution. Issue #70 remains evidence-gated; Apple remains deferred under Issue #123. +Finish PR #144 exact-head certification and merge only if all required checks pass at the unchanged head. Defer third-party Windows trust-signing provider qualification/integration until future owner authorization; continue safe authorized repository work independently. Keep M14 at 70% until real external evidence gates pass. Do not deploy, restore, publish, sign or run Runner tasks without separate authority. diff --git a/tests/frontend/ai-supervisor-control-plane.test.mjs b/tests/frontend/ai-supervisor-control-plane.test.mjs index 9232928d..37f74138 100644 --- a/tests/frontend/ai-supervisor-control-plane.test.mjs +++ b/tests/frontend/ai-supervisor-control-plane.test.mjs @@ -29,6 +29,12 @@ test('compact AI supervisor state is machine-readable, bounded and resume-safe', assert.equal(state.fallback_work_policy.automatic_selection,true) assert.equal(state.fallback_work_policy.stop_early_to_conserve_tokens,false) assert.equal(state.fallback_work_policy.may_invent_product_scope,false) + assert.equal(state.fallback_work_policy.state_pointer_only_drift_is_actionable,false) + assert.equal(state.state_sync_policy.observed_main_sha_is_resume_anchor_not_live_authority,true) + assert.equal(state.state_sync_policy.recursive_post_merge_state_only_pr_forbidden,true) + assert.equal(state.state_sync_policy.pointer_only_drift_reconciled_in_memory,true) + assert.equal(state.state_sync_policy.semantic_status_drift_requires_source_sync,true) + assert.equal(state.state_sync_policy.merge_evidence_may_live_on_pr_issue_until_next_substantive_mutation,true) assert.deepEqual(state.fallback_work_policy.order,[ 'accepted_open_pr_repair_review_merge', 'accepted_actionable_open_issue', @@ -149,6 +155,12 @@ test('Continuous Fast-Batch chains safe milestones without routine user confirma assert.equal(claims.claims.find(x=>x.id==='CLAIM-018')?.value,true) assert.equal(claims.claims.find(x=>x.id==='CLAIM-019')?.value,false) assert.equal(claims.claims.find(x=>x.id==='CLAIM-020')?.value,true) + assert.equal(claims.claims.find(x=>x.id==='CLAIM-021')?.value,false) + assert.equal(claims.claims.find(x=>x.id==='CLAIM-022')?.value,false) + assert.equal(claims.claims.find(x=>x.id==='CLAIM-023')?.value,true) + assert.ok(agents.includes('Post-merge recursion guard')) + assert.ok(agents.includes('expected post-merge pointer drift')) + assert.ok(fastBatch.includes('must not spawn a recursive state-only PR')) assert.ok(agents.includes('Mandatory fallback work scan')) assert.ok(agents.includes('Do not voluntarily stop merely to conserve tokens/context')) assert.ok(fastBatch.includes('mandatory fallback scan')) diff --git a/tools/ai-supervisor-state-audit.mjs b/tools/ai-supervisor-state-audit.mjs index 5389e69e..df4166d5 100644 --- a/tools/ai-supervisor-state-audit.mjs +++ b/tools/ai-supervisor-state-audit.mjs @@ -5,7 +5,7 @@ for(const x of Object.values(p))if(!fs.existsSync(x))fail('missing '+x) for(const [x,max] of [[p.state,12*1024],[p.checkpoint,16*1024],[p.journal,32*1024]])if(fs.statSync(x).size>max)fail(x+' exceeds compact size limit') const parse=x=>{try{return JSON.parse(fs.readFileSync(x,'utf8'))}catch(e){fail(x+' must remain JSON-compatible YAML: '+e.message)}} const s=parse(p.state),q=parse(p.queue),c=parse(p.claims),r=parse(p.runner),a=fs.readFileSync(p.agents,'utf8'),cp=fs.readFileSync(p.checkpoint,'utf8'),readme=fs.readFileSync('README.md','utf8') -for(const k of ['observed_main_sha','active_issue','active_pr','active_branch','current_milestone','milestone_status','last_completed_milestone','exact_next_safe_action','pending_runner_ids','blocked_runner_ids','current_blockers','timeout_control','fallback_work_policy','response_status'])if(!(k in s))fail('CURRENT-STATE missing '+k) +for(const k of ['observed_main_sha','active_issue','active_pr','active_branch','current_milestone','milestone_status','last_completed_milestone','exact_next_safe_action','pending_runner_ids','blocked_runner_ids','current_blockers','timeout_control','fallback_work_policy','state_sync_policy','response_status'])if(!(k in s))fail('CURRENT-STATE missing '+k) if(s.compact_state_path!=='docs/ai-state')fail('compact_state_path mismatch') if(!/^[0-9a-f]{40}$/i.test(s.observed_main_sha||''))fail('observed_main_sha invalid') if(!['PLANNING','IMPLEMENTING','VERIFYING','WAITING_EXTERNAL','BLOCKED','COMPLETE'].includes(s.milestone_status))fail('milestone_status unsupported') @@ -23,6 +23,13 @@ const fw=s.fallback_work_policy if(!fw||fw.enabled!==true||fw.scan_before_terminal_handoff!==true||fw.automatic_selection!==true)fail('fallback work policy must stay enabled and automatic') if(fw.stop_early_to_conserve_tokens!==false)fail('fallback policy must forbid voluntary token-conservation stop') if(fw.may_invent_product_scope!==false)fail('fallback policy must not invent product scope') +if(fw.state_pointer_only_drift_is_actionable!==false)fail('pointer-only state drift must not be standalone fallback work') +const sp=s.state_sync_policy +if(!sp||sp.observed_main_sha_is_resume_anchor_not_live_authority!==true)fail('observed main SHA must remain a resume anchor') +if(sp.recursive_post_merge_state_only_pr_forbidden!==true)fail('recursive post-merge state-only PRs must be forbidden') +if(sp.pointer_only_drift_reconciled_in_memory!==true)fail('pointer-only drift must reconcile in memory') +if(sp.semantic_status_drift_requires_source_sync!==true)fail('semantic status drift must require source sync') +if(sp.merge_evidence_may_live_on_pr_issue_until_next_substantive_mutation!==true)fail('merge evidence deferral contract missing') const fallbackOrder=['accepted_open_pr_repair_review_merge','accepted_actionable_open_issue','ci_test_security_review_audit_state_branch_repair','authorized_dependency_supply_chain_maintenance','docs_compact_state_readme_coordination_lifecycle_reconciliation','non_destructive_evidence_diagnostics_for_existing_blocker'] if(JSON.stringify(fw.order)!==JSON.stringify(fallbackOrder))fail('fallback work order drifted') const rs=s.response_status @@ -61,5 +68,5 @@ const runnerIds=new Set((r.entries||[]).map(x=>x.id)) for(const k of ['pending_runner_ids','blocked_runner_ids'])for(const id of s[k])if(!runnerIds.has(id))fail(k+' references missing '+id) for(const id of s.blocked_runner_ids){const e=r.entries.find(x=>x.id===id);if(e?.definition_status!=='blocked')fail(id+' is not blocked in registry')} for(const m of ['## Verified','## Not Verified','## Known Risk','## Next Action'])if(!cp.includes(m))fail('LAST-CHECKPOINT missing '+m) -for(const m of ['docs/ai-state/CURRENT-STATE.yaml','Runner registration NEVER grants execution authority','at most one consolidated CI/status refresh','OPEN GitHub Issues first','Message delivery timed out','Repo:','Current Work:','Current Module:','Module Progress:','Overall Progress:','README progress synchronization contract','every completed milestone','Fast-Batch default','Continuous autonomous execution window','Milestone completion is a checkpoint','Do **not** ask the user to diagnose or confirm a technical repair','A single blocked lane','Mandatory fallback work scan','Do not voluntarily stop merely to conserve tokens/context'])if(!a.includes(m))fail('AGENTS missing '+m) +for(const m of ['docs/ai-state/CURRENT-STATE.yaml','Runner registration NEVER grants execution authority','at most one consolidated CI/status refresh','OPEN GitHub Issues first','Message delivery timed out','Repo:','Current Work:','Current Module:','Module Progress:','Overall Progress:','README progress synchronization contract','every completed milestone','Fast-Batch default','Continuous autonomous execution window','Milestone completion is a checkpoint','Do **not** ask the user to diagnose or confirm a technical repair','A single blocked lane','Mandatory fallback work scan','Do not voluntarily stop merely to conserve tokens/context','Post-merge recursion guard','expected post-merge pointer drift'])if(!a.includes(m))fail('AGENTS missing '+m) console.log('AI supervisor compact state valid.') diff --git a/tools/e2e-server-supervisor.mjs b/tools/e2e-server-supervisor.mjs new file mode 100644 index 00000000..926e4247 --- /dev/null +++ b/tools/e2e-server-supervisor.mjs @@ -0,0 +1,161 @@ +import { spawn } from 'node:child_process' +import path from 'node:path' +import process from 'node:process' + +const root = path.resolve(import.meta.dirname, '..') +const configuredBase = process.env.WORKINTEL_E2E_BASE_URL || 'http://127.0.0.1:8777' +const base = new URL(configuredBase) +const hostname = base.hostname.replace(/^\[|\]$/g, '') +const allowedHosts = new Set(['127.0.0.1', 'localhost', '::1']) + +if (base.protocol !== 'http:' || !allowedHosts.has(hostname)) { + console.error('[e2e-server-supervisor] Refusing to start a local server unless the E2E base URL is local HTTP.') + process.exit(1) +} + +const host = hostname === 'localhost' ? '127.0.0.1' : hostname +const port = Number(base.port || 80) +const healthURL = new URL('/health/live', base).toString() +const probeIntervalMs = 2_000 +const probeTimeoutMs = 3_000 +const startupGraceMs = 45_000 +const unhealthyProbeLimit = 3 +const maxRestarts = 2 + +let server = null +let serverSpawnError = null +let serverExit = null +let serverStartedAt = 0 +let consecutiveFailures = 0 +let restartCount = 0 +let stopping = false + +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) +const log = message => console.log(`[e2e-server-supervisor] ${message}`) + +function startServer() { + serverSpawnError = null + serverExit = null + serverStartedAt = Date.now() + server = spawn('php', ['artisan', 'serve', '--no-reload', `--host=${host}`, `--port=${port}`], { + cwd: root, + env: process.env, + stdio: 'inherit', + windowsHide: true, + }) + + server.once('error', error => { + serverSpawnError = error + console.error(`[e2e-server-supervisor] Laravel server process error: ${error.message}`) + }) + server.once('exit', (code, signal) => { + serverExit = { code, signal } + if (!stopping) log(`Laravel server exited (code=${code ?? 'null'}, signal=${signal ?? 'none'}).`) + }) + log(`Started Laravel server PID ${server.pid ?? 'unavailable'} at http://${host.includes(':') ? `[${host}]` : host}:${port}.`) +} + +async function isHealthy() { + const controller = new AbortController() + const timeout = setTimeout(() => controller.abort(), probeTimeoutMs) + + try { + const response = await fetch(healthURL, { signal: controller.signal }) + await response.body?.cancel() + return response.ok + } catch { + return false + } finally { + clearTimeout(timeout) + } +} + +async function terminateServer() { + const current = server + if (!current) return + + const exited = new Promise(resolve => { + if (current.exitCode !== null || current.signalCode !== null || serverExit) { + resolve() + } else { + current.once('exit', resolve) + } + }) + + if (current.pid && process.platform === 'win32' && !serverExit) { + await new Promise(resolve => { + const killer = spawn('taskkill.exe', ['/pid', String(current.pid), '/t', '/f'], { + stdio: 'ignore', + windowsHide: true, + }) + killer.once('error', () => { + current.kill('SIGTERM') + resolve() + }) + killer.once('close', resolve) + }) + } else if (!serverExit) { + current.kill('SIGTERM') + } + + await Promise.race([exited, delay(5_000)]) + if (current.exitCode === null && current.signalCode === null && !serverExit) current.kill('SIGKILL') + if (server === current) server = null +} + +async function stop(exitCode = 0) { + if (stopping) return + stopping = true + await terminateServer() + process.exitCode = exitCode +} + +async function recover(reason) { + if (restartCount >= maxRestarts) { + console.error(`[e2e-server-supervisor] Circuit breaker stopped recovery after ${restartCount} restarts: ${reason}`) + await stop(1) + return + } + + restartCount += 1 + console.error(`[e2e-server-supervisor] Restarting Laravel server (${restartCount}/${maxRestarts}): ${reason}`) + await terminateServer() + await delay(500 * restartCount) + consecutiveFailures = 0 + startServer() +} + +async function supervise() { + startServer() + + while (!stopping) { + await delay(probeIntervalMs) + if (stopping) break + + if (serverSpawnError || serverExit || !server || server.exitCode !== null || server.signalCode !== null) { + const reason = serverSpawnError?.message || `process exit ${JSON.stringify(serverExit)}` + await recover(reason) + continue + } + + const healthy = await isHealthy() + if (healthy) { + consecutiveFailures = 0 + continue + } + + if (Date.now() - serverStartedAt < startupGraceMs) continue + consecutiveFailures += 1 + if (consecutiveFailures >= unhealthyProbeLimit) { + await recover(`health endpoint failed ${consecutiveFailures} consecutive probes`) + } + } +} + +process.once('SIGINT', () => { void stop(0) }) +process.once('SIGTERM', () => { void stop(0) }) + +supervise().catch(async error => { + console.error(`[e2e-server-supervisor] Fatal supervisor error: ${error.stack || error.message}`) + await stop(1) +}) diff --git a/tools/playwright.config.mjs b/tools/playwright.config.mjs index 9cc8ca18..50d8b530 100644 --- a/tools/playwright.config.mjs +++ b/tools/playwright.config.mjs @@ -68,7 +68,7 @@ export default defineConfig({ video: 'off', }, webServer: { - command: 'php artisan serve --no-reload --host=127.0.0.1 --port=8777', + command: 'node tools/e2e-server-supervisor.mjs', cwd: root, url: `${baseURL}/health/live`, reuseExistingServer: false,