Autonomous Jobjakt backlog controller
For your normal Windows login and existing ChatGPT account, use single-user setup. It requires no second Windows account, subscription or VM. The new default is an operator-controlled pause, with explicit MXC qualification before unattended work. The separate-identity instructions below describe the optional legacy dedicated-runner mode only. Neither mode activates the roadmap automatically.
This implementation builds the orchestrator only. The real backlog is disabled. Phase 10 is NO-GO pending its own entry decision. See audit, gate register, security boundary, and acceptance evidence.
What is installed
scripts/Run-JobjaktBacklog.ps1 provides the Windows command interface. automation/controller.py uses Python's standard library; no package installation or application service is required for controller tests. automation/backlog.json preserves sequence 05–11 with 49 bounded checkpoints and full source snapshots. Runtime state, approvals, reports and logs belong in a separate protected ControlRoot, never in the model-writable repository. JSON is sufficient because one controller owns an OS-held repository lock and all state writes are atomic/checksummed; SQLite would add no useful concurrency here.
Requirements: PowerShell 7.2+, Python 3.12+, Git and Codex CLI 0.163.0 (the version audited here; qualify later versions before unattended use). codex exec structured output and sandbox flags are described in the official non-interactive documentation. Windows 0.163.0 runs test commands as codex sandbox -C <workspace> -c sandbox_mode="workspace-write" <command> ...; see local help and the Windows sandbox documentation.
Commands already safe to run now
The validation installation at C:\Users\Connor\.codex\orchestrator-validation\autonomous-roadmap-01-final is a disabled snapshot for dry runs. It references the separate implementation worktree. It is not a qualified unattended deployment; start/resume cannot launch the real queue while disabled.
$control = 'C:\Users\Connor\.codex\orchestrator-validation\autonomous-roadmap-01-final'
$run = Join-Path $control 'Run-JobjaktBacklog.ps1'
pwsh -NoProfile -File $run -Command validate -ControlRoot $control
pwsh -NoProfile -File $run -Command dry-run -ControlRoot $control
pwsh -NoProfile -File $run -Command status -ControlRoot $control
pwsh -NoProfile -File $run -Command current -ControlRoot $control
pwsh -NoProfile -File $run -Command logs -ControlRoot $control
Run the reproducible isolated tests from this implementation worktree:
Set-Location 'C:\Users\Connor\.codex\worktrees\autonomous-roadmap-01\Job tracker'
python -m unittest discover -s automation/tests -v
pwsh -NoProfile -File automation/tests/Test-Approvals.ps1 -Verifier "$PWD\scripts\Approve-JobjaktBacklog.ps1"
Tests create disposable local worker repositories and bare remotes. The subprocess double exercises the real supervision/result/report paths without a model or network. RSA tests use temporary in-memory keys/certificates and do not install an owner key. They do not qualify the Windows sandbox or real application acceptance.
Optional legacy dedicated-runner provisioning
Use a dedicated development Windows account/VM with no production credentials, mounts, Docker socket, remote admin access or production network routes. Keep the owner's signing identity separate. A source worktree provides edit isolation; it is not a production security boundary. Prefer a separate clone for unattended execution, avoiding shared Git metadata/hooks with ongoing human work. The owner must protect main/production refs server-side and grant the publisher only the intended development refs.
Create the runner clone from the accepted development branch after its final publication; never default to main. Do not copy private .env files from the live checkout. Configure Git author identity and an approved development-only credential helper. Install dependencies and qualify local synthetic service fixtures separately. Do not let the controller install infrastructure or enable workers on your behalf.
Initialize a new control directory using the implementation source:
$source = 'C:\Users\Connor\.codex\worktrees\autonomous-roadmap-01\Job tracker'
pwsh -NoProfile -File "$source\scripts\Run-JobjaktBacklog.ps1" `
-Command init -ControlRoot 'C:\JobjaktControl' -Repository 'C:\JobjaktWorker'
init snapshots code, schemas, source prompts and initial manifest outside the worker. It refuses to overwrite existing state. Keep the trusted installation read-only to model shell commands, with the runner able to persist its state and reports outside the sandbox. The owner provisions ACLs/VM policy; this task does not change machine accounts, firewall or system permissions.
Edit protected config.json as the operator: exact worker path; Codex/pwsh executable paths; owner SID; separate runner SID; public certificate filename/SHA256; dedicated auth-only workerCodeXHome; time/log budgets; optional execution windows. Authenticate as the development runner with codex login using that dedicated CODEX_HOME. Never print/copy auth tokens into logs. Default child environment excludes API-key/production secret variables. Do not use the owner's normal CODEX_HOME with its plugins or credentials.
Real execution verifies the runner identity, certificate pin, version, disjoint paths, auth-only configuration and a negative sandbox write probe. It refuses missing/failed sandbox controls and never falls back to unrestricted execution. The current host's CryptUnprotectData error must be resolved and the real boundary qualified before any worker can run. A signed environment qualification additionally records OS ACLs, read/network access, CPU/RAM quotas, synthetic service isolation and credential exposure: a successful single write probe cannot certify all of these.
The security source pack requires Codex Security plugins and actual scanner artifacts. The default auth-only worker intentionally has no plugin capability. A platform owner can provision a vetted, constrained development-only plugin/MCP runner and add explicit trustedCodexOverrides entries (key under mcp_servers.* or plugins.*, plus its exact TOML toml value) to protected config. Other override namespaces are rejected; explicit sandbox/approval flags remain fixed. This changes the policy hash and requires fresh signed environment/roadmap approval. Qualify every server's identity, permissions, egress, costs and tool exposure before signing: MCP/plugin tools are not automatically confined by the shell sandbox. Missing required scan capability remains BLOCKED. Do not remove source requirements or use unrestricted config loading to make a scan appear to pass.
Configure gates and enable the exact queue
The core backend/frontend/type/lint/build commands are specified. The composite provider/browser/Python/PDF/security/preservation adapter is marked configured:false. Before real execution, the platform owner must install its actual checkpoint-specific commands and structured report definitions in a proposed manifest, with exact test-suite membership (expectedNames) or a trusted independently verified membership adapter. Use original preservation/PDF oracles; do not rewrite them to match current failures. Human/provider/hosted/model requirements remain separate signed evidence decisions. No successful dry run changes these gates.
Copy backlog.json to proposed-backlog.json in ControlRoot. Set the exact accepted/published baseline commit and branch, resolved branch/substage policy, qualified checks/artifacts, and finally executionEnabled:true. Do this only after the owner explicitly authorizes first execution. Never modify active state JSON to enable it.
pwsh -NoProfile -File C:\JobjaktControl\Run-JobjaktBacklog.ps1 `
-Command configure -ControlRoot C:\JobjaktControl -Manifest C:\JobjaktControl\proposed-backlog.json
The first invocation writes a manifest-policy-update request and exits without applying the policy. Sign that request through the protected owner workflow below, then run the same command again. It adopts the manifest without resetting completed work. Started-stage policy is immutable. A crash between policy/state writes fails closed; restore the verified previous pair from operator backups rather than guessing which policy ran.
Owner signing and decisions
On the owner's separate Windows identity or machine, create a nonexportable signing key once:
pwsh -NoProfile -File .\Approve-JobjaktBacklog.ps1 -Action NewKey
pwsh -NoProfile -File .\Approve-JobjaktBacklog.ps1 -Action ExportPublicKey `
-Thumbprint '<OWNER_CERTIFICATE_THUMBPRINT>' -CertificatePath .\owner.cer
Get-FileHash .\owner.cer -Algorithm SHA256
Record the printed owner SID and certificate hash in the protected runner configuration. Transfer only owner.cer to the runner, never a PFX/private key. A certificate file placed inside a worker checkout is not a protected approval mechanism.
status shows the exact pending request path. Review that JSON and its linked source/evidence. Transfer the exact request bytes to the owner; signing does not alter them. Example:
pwsh -NoProfile -File .\Approve-JobjaktBacklog.ps1 -Action Sign `
-RequestPath '.\requests\<REQUEST_SHA256>.json' `
-ApprovalPath '.\approvals\<REQUEST_SHA256>.json' `
-Thumbprint '<OWNER_CERTIFICATE_THUMBPRINT>' -ExpectedOwnerSid '<OWNER_SID>' `
-Disposition Approve -Decision 'Approve the exact stated scope and evidence' -ValidHours 72
Transfer the signed envelope to C:\JobjaktControl\approvals\<REQUEST_SHA256>.json, then resume. The controller checks its signature, owner, certificate pin, request digest and expiry. Editing a worker approval.json or copying a previous commit's approval will not work.
For homepage feedback, sign the pending design request with -Disposition Revise -Decision 'Keep concept A layout; use D buttons; revise mobile spacing', transfer it, then resume. The next session revises the same checkpoint using that exact decision. After the revised artifacts are published, approve the new request with your final selection. Reject blocks advancement. The model never chooses on your behalf. Signed decision text is passed to subsequent sessions, so no roadmap prompt copying is needed.
Environment and roadmap-execution approval are shared for the exact queue policy; later stages reuse those grants while they remain valid. Scope-specific grants, Product Review selection, language review, design choice, security decisions and final requirement reviews are still required at their actual checkpoints. If a grant expires before use, renew that exact request; an accepted earlier checkpoint is not silently undone by a later expiry.
Start, monitor, pause, resume and retry
These commands are for the qualified, explicitly enabled installation only:
$run = 'C:\JobjaktControl\Run-JobjaktBacklog.ps1'
pwsh -NoProfile -File $run -Command start -ControlRoot C:\JobjaktControl
pwsh -NoProfile -File $run -Command status -ControlRoot C:\JobjaktControl
pwsh -NoProfile -File $run -Command current -ControlRoot C:\JobjaktControl
pwsh -NoProfile -File $run -Command logs -ControlRoot C:\JobjaktControl
pwsh -NoProfile -File $run -Command pause -ControlRoot C:\JobjaktControl
pwsh -NoProfile -File $run -Command resume -ControlRoot C:\JobjaktControl
pwsh -NoProfile -File $run -Command retry -ControlRoot C:\JobjaktControl -Stage PHASE-10
start stays in the foreground until the queue completes, hits a genuine gate or reaches a configured window/budget. Use a separate terminal for monitoring/pause. pause writes a durable request without racing the controller's state lock; supervision stops the active child tree. resume clears the pause and runs the next allowed work. Ordinary failures receive bounded remediation sessions with failure context; retry never silently resets an exhausted budget. Its explicit reset request requires a signed owner decision. Session totals remain capped even after resetting attempts.
The state store records initial/accepted commits, checkpoint progress, attempts/sessions, pending publication, approvals, tests, artifacts, reports and recent sessions. NOT_RUN is distinct from verified zero failures. Status never combines overlapping suite counts into one roadmap total.
Recovery
- Push/network failure: local verified commits remain. Restore development remote access and run
resume. Only that publication is retried; the model and tests are not repeated for an unchanged candidate. Remote HEAD mismatch or non-fast-forward stops advancement. No force push/rebase/main merge occurs. - CLI failure/context limit: failed/incomplete output cannot advance. Retry/continuation starts a fresh bounded session with full applicable prompt, stored result, source identities, prior decisions and failures. CLI thread IDs are recorded for inspection; raw
exec resume --lastis deliberately avoided because it can select unrelated work or inherit unsuitable permissions. - Parent killed/reboot: the OS releases the Git lock. A persistent active-process marker or RUNNING state blocks a new worker. Inspect recorded PID, creation time/session/command and all descendants before stopping an orphan; never kill a reused PID blindly. After the tree is gone, run
recover, sign its exact reconciliation request, then rerunrecoverandresume. A launch marker with no PID requires operator inspection/clearance, not an automatic guess. Native time limits apply while the controller lives; VM/Task Scheduler job limits are required for hard orphan resource bounds. - Corrupt state: checksum failure loads the last verified backup and sets recovery-required. It does not restart from zero.
recoverrequires a signed owner reconciliation. If both copies are corrupt, restore a verified state + manifest + reports backup; do not runinitover the installation. Restore/reconcile exact Git HEAD and remote publication before resuming. - Unexpected source/Git/policy changes: stop and investigate. Resume refuses changed prompt hashes, unexpected branch/HEAD, altered evidence, diverged integration or modified manifest. Preserve logs and local commits. Do not reset the worker or silently remove tests.
Scheduling and resource limits
No task or recurring automation is installed by this build. The CLI works without an interactive GUI. An optional Windows Task Scheduler task may invoke the installed start command at logon/startup and/or a periodic interval under the dedicated runner. start continues existing state while respecting a durable manual pause; reserve resume for the owner's deliberate unpause. Use Run whether user is logged on or not, Run with highest privileges disabled, a maximum duration and Do not start a new instance. The repository lock remains the final concurrency guard. Do not use the owner signing account as the scheduled worker.
Example task action (configure it through Task Scheduler after approval):
Program: <absolute path to pwsh.exe>
Arguments: -NoProfile -File C:\JobjaktControl\Run-JobjaktBacklog.ps1 -Command start -ControlRoot C:\JobjaktControl -Python <absolute path to python.exe>
Start in: C:\JobjaktControl
The PC must be awake, with its approved development fixtures, authentication, dependencies and remote available. The controller does not bypass lock/sleep or wake the computer. executionWindows uses the Windows runner's local time; configure its timezone as Europe/Paris if that is the intended window. Overnight windows are supported and a running session stops when its window closes. Defaults are no time window, eight-hour controller budget, two-hour sessions, one-hour checks, 50 MiB per output stream, 64 processes and 8 GiB total child-tree memory. Windows Job Objects enforce process/memory/kill-on-close limits after a suspended launch; CPU and whole-host limits still belong to the qualified VM. Limits stop continuation; they do not assert completion.
Notifications are local sanitized events.jsonl records and terminal status. No paid provider is added. Existing Jobjakt user notifications belong to the application and are not reused for developer orchestration. Event records contain IDs/status, never documents or credentials; an operator can attach an approved local event watcher later. Full session files remain private access-controlled evidence. No unchanged-state notification loop is created.
Add future prompts
Preserve original bytes and record SHA256. automation/prepare_queue.py --source <folder> --output <new-folder> --project <repository> imports the actual mapped pack into a new queue, refusing to overwrite one. Add stable workstream IDs/dependencies, exact branch/checkpoint policies, source/supplement hashes, all required gates/checks/artifacts/owner decisions and finite budgets. Validate source identity and qualify tests in a disposable repository. Adding IDs needs a new installation/owner-reviewed queue migration; configure deliberately cannot splice new stages into a running queue. Never derive authorization from a filename such as done.
Exact first owner action
Finish pre-Phase-10 acceptance and explicitly approve Phase 10 development entry on a named, published baseline and candidate scope. This is not yet granted. Publish/verify the pending pre-Phase-10 commits, disposition the scoped CV/PDF/human/AI/CI/security conditions according to their actual gate authority, qualify the isolated runner and test adapters, then sign the proposed enabled policy, environment/roadmap grants and phase10-development-entry request. Until those steps, use the disabled dry-run installation. No real backlog command was executed by this task.