5.8 KiB
P1 manual configuration acceptance
This walkthrough is an independent human gate for the P1 workspace configuration process. The
reviewer—not the helper—performs the HTTP, Git, export, rendering, and tht checks and judges the
result. Automation never creates VERDICT.md, never records PASS, and never consumes or copies
.artifacts/p1-integration.
Prerequisites
From a clean repository checkout, Task 8 must already be implemented. Install Node/npm, python3,
and Git, curl, unzip/zipinfo, lsof, and the harness development environment so
harness/.venv/bin/tht is executable.
Ports 127.0.0.1:8791 and 127.0.0.1:8792 must be free. The helper builds and serves only the
production backend; it does not start Docker or the frontend.
Lifecycle
Run these commands from the repository root:
./scripts/p1-manual-acceptance.sh prepare
./scripts/p1-manual-acceptance.sh serve
./scripts/p1-manual-acceptance.sh stop
./scripts/p1-manual-acceptance.sh cleanup
prepare exclusively creates .artifacts/manual-acceptance/p1/, with fresh Git history, fixtures,
secret files, concrete request/inspection commands, and GUIDE.md. It also creates the single regular
logs/backend.log with mode 0600 and records its exact path/device/inode ownership. It creates no
supervisor or readiness-status program/file, leaves status PENDING and the server stopped, and
refuses an existing root; use the guarded stop and cleanup actions rather than deleting or reusing
state manually.
serve holds the external lifecycle lock, validates the canonical production
backend/dist/server.js, every owned root/runtime/log ancestor, the absence of a legacy supervisor,
and the original log identity before spawning. The log is opened with no-follow semantics and its
file descriptor is passed directly to the child. The child is the production Node entrypoint itself:
node --import data:text/javascript;base64,<immutable-preload> backend/dist/server.js followed by the
three ownership/control arguments. The immutable preload owns only an authenticated fixed
127.0.0.1:8792 control channel and a bounded startup watchdog; the application binds
127.0.0.1:8791 normally. Before writing the RUNNING PID record, the parent requires an exact
nonce-bound control STATUS and a 2xx GET /health, then sends READY to disarm the watchdog. A startup
or non-2xx failure requests nonce-authenticated STOP (or lets the watchdog self-exit) and leaves no
listener or PID record.
stop revalidates the exact executable, immutable preload, production script, arguments, repository
cwd/root, and process start identity, then requests STOP over the nonce-authenticated cooperative
channel and requires the exact acknowledgement. The controlled process acknowledges and exits itself;
the production tool never sends a numeric terminating signal. serve, stop, and cleanup are
serialized; ambiguous, stale, or starting records remain for operator inspection. cleanup removes
only the exact stopped owned fixed root. Foreign siblings and automated integration artifacts are
outside its cleanup boundary.
After prepare, follow the 14 ordered steps in the generated absolute-path GUIDE.md. Personally run each generated http-01 through http-14 curl script in numeric order; they save the exact status, three validation, three sequential publication, pull, three read responses, and three ZIP exports. Each publication derives its current base commit with a bounded parser from the preceding saved API response, with no placeholder base. Run the five numbered negative validation scripts separately at checklist step 10. The render commands validate the bounded saved read response,
its commit-addressed owned snapshot path, the saved publish commit, and the installed Git HEAD before
calling the acceptance-only production renderer. The renderer imports the built ThtRunner, resolves
bindings from environment paths, copies one lease atomically with mode 0600, and releases it in
finally. For each exported ZIP, invoke the generated extractor with the exact expected workspace ID
(p1-filesystem, p1-http, or p1-s3); its python3 helper opens the source once, stages and
revalidates its SHA-256, anchors every extraction and cleanup operation to an opened no-follow
exports/extracted directory descriptor, and binds both the manifest and parsed descriptor identity
to that expected ID. It verifies exactly four regular entries and publishes only their exact checked
bytes. The generated secret scan reads every bounded filesystem file outside the direct
fixture-secrets directory, including Git metadata and arbitrary .git-named directories, then
enumerates every reachable or unreachable Git object and scans the bounded raw blob, commit, tree,
and tag bytes. Findings redact canary values. Do not inspect or print raw secret-file contents; only
inspect ownership/mode/path metadata and canary absence outside fixture-secrets.
Failures and verdict
On failure, run stop if the owned server is running and preserve the entire fixed root for review.
Do not run cleanup until evidence is no longer needed. A reviewer creates VERDICT.md only after the
walkthrough, containing:
- reviewer identity;
- UTC timestamp;
- an explicit result for every one of the 14 generated checklist steps;
- observations and failure evidence;
- exactly
manual acceptance: PASSormanual acceptance: FAIL.
Passing bash scripts/test-p1-manual-acceptance.sh proves only that the tooling guards work. It does
not perform or approve manual acceptance and leaves the project-level manual status PENDING.
Expected safe outcomes are one listener on 127.0.0.1:8791; 2xx positive responses; non-2xx negative validations without Git or snapshot mutation; an empty render diff; two successful tht config check calls; no manifest, Evidence/export, secret, or out-of-scope-artifact finding; and no PID or listener after stop.