You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
M2-11: Create Web/API baseline and strict request contracts #32
Build only the approved app skeleton, strict request/health contracts, Fake service boundary, contract tests, and reproducible production start.
No real Moss orchestration, Decision Engine orchestration, preflight-core business logic, or Clear402 behavior.
Pin exact framework versions.
Next resolved sharp@0.34.5; any build-script allowlist entry must be explicit, reviewed, pinned, and documented. Do not bypass pnpm supply-chain policy.
Issue #32 is now the single active Builder slot and is moved to Project In Progress for planning.
Planned branch name after scope confirmation: codex/issue-32-web-api-baseline
Planned isolated worktree after scope confirmation: /Users/qy/Documents/moss-mini-demo-issue-32
The first required evidence is a closed, path-specific Work Plan that freezes exact framework versions, writable paths, public/server boundaries, strict request and health contracts, Fake service contract, production build/start smoke, tests, and dependency changes.
In Progress starts planning only. It is not SCOPE_CONFIRMED, implementation authorization, QA PASS, Review, Merge Gate, or merge authorization. No branch, worktree, file modification, dependency update, commit, push, or PR may begin before Maintainer scope confirmation.
Issue #23 and newly released #25 remain Ready and unassigned. Other M2 Issues retain their existing blocked dependency gates.
Planned branch after authorization: codex/issue-32-web-api-baseline.
Planned isolated worktree after authorization: /Users/qy/Documents/moss-mini-demo-issue-32.
This Work Plan is the complete implementation request. No branch, worktree, file, dependency, lockfile, commit, push, deployment, or PR may be created before a Maintainer records explicit SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZED.
2. Goal and delivery boundary
Build a production-buildable and production-startable Next.js App Router skeleton on the accepted Node runtime, with:
strict and versioned POST /api/preflight request/response contracts;
strict GET /api/health response fields;
fixed request and response byte limits;
server-generated run identifiers;
an offline Fake service implementing the same server service interface later used by real orchestration;
exact fixture scenario allowlisting;
explicit server-only ownership;
automated production start/health and browser-bundle leakage smoke tests.
This issue creates an application/API baseline, not an integrated demo. It does not implement Moss orchestration, Quote collection, Capability construction, simulation, Alignment, Decision Engine orchestration, report assembly, Monad/RPC access, Clear402 behavior, wallet behavior, signing, or transaction submission.
No caret, tilde, tag, floating version, or additional dependency is authorized. The existing root TypeScript 7.0.2, Vitest 4.1.10, and Biome 2.5.5 remain the only compiler/test/format toolchain.
sharp@0.34.5 is a reviewed direct runtime dependency because Next production image handling resolves it and its install script must not be silently blocked or broadly enabled. pnpm-workspace.yaml will contain exactly:
No dangerouslyAllowAllBuilds, wildcard build permission, ignored-build bypass, or second build-script allowlist entry is authorized. The lockfile must resolve Sharp exactly to 0.34.5 and retain package integrity metadata. A clean-store install must prove the reviewed Sharp script succeeds, and a Node import must report Sharp 0.34.5.
4. Closed writable path list
Exactly these 30 repository paths are writable:
.gitignore - ignore Next build output only.
package.json - add exact root web scripts/order; do not change existing dependency versions.
pnpm-lock.yaml - generated frozen dependency graph and one apps/web importer only.
pnpm-workspace.yaml - register apps/* and allow only the pinned Sharp build script.
tsconfig.json - keep root strict checking but delegate apps/web to its own Next config.
README.md - minimal stable current-state correction for the Web/API baseline.
SECURITY.md - minimal stable boundary correction; no weakening of exclusions.
docs/real-vs-mock.md - identify the Fake service and Fixtures as synthetic/non-evidence.
apps/web/package.json
apps/web/tsconfig.json
apps/web/next-env.d.ts
apps/web/next.config.ts
apps/web/app/globals.css
apps/web/app/layout.tsx
apps/web/app/page.tsx
apps/web/app/api/health/route.ts
apps/web/app/api/preflight/route.ts
apps/web/src/contracts/health.ts
apps/web/src/contracts/preflight.ts
apps/web/src/server/moss-build-info.ts
apps/web/src/server/run-id.ts
apps/web/src/server/http-json.ts
apps/web/src/server/preflight-service.ts
apps/web/src/server/fake-preflight-service.ts
apps/web/src/server/preflight-handler.ts
apps/web/test/contracts.test.ts
apps/web/test/fake-preflight-service.test.ts
apps/web/test/routes.test.ts
apps/web/test/browser-bundle-leak.smoke.mjs
apps/web/test/production-start.smoke.mjs
There is no wildcard writable path. No generated asset, snapshot, public directory, fixture, application package, or 31st path may be added. In particular, this issue must not modify .github/workflows/quality-gate.yml, .gitmodules, vendor/moss, any packages/report-schema or packages/decision-engine file, any ADR, docs/architecture.md, docs/security-boundary.md, or STOP presentation rules.
5. Workspace, build, and script contract
.gitignore adds .next/. No source path is ignored.
The root tsconfig.json continues strict no-emit validation for existing root/package code and excludes apps/**; apps/web/tsconfig.json owns DOM, JSX, Next plugin, JSON-module, incremental, and generated Next type settings. The committed next-env.d.ts uses only stable Next type references and does not import a missing .next artifact, so zero-artifact typecheck remains valid. Root typecheck must explicitly invoke the Web package typecheck so exclusion cannot become a coverage gap.
Root scripts retain the existing gate and use these exact semantics:
dev: next dev
start: next start
build: build @moss-mini-demo/report-schema, then next build
typecheck: build @moss-mini-demo/report-schema, then tsc --noEmit
The public report package is built first so pnpm --filter @moss-mini-demo/web build and Web typecheck work in a clean checkout with no pre-existing dist. No TypeScript path alias to package-private source, committed dist, hidden lifecycle script, or postinstall hook is permitted. Test code cannot invoke a build; the existing root test script keeps its explicit build prerequisite visible.
pnpm-lock.yaml changes are limited to:
the new apps/web importer;
the exact direct dependencies listed above;
their pnpm-resolved transitive graph, platform-specific Next SWC packages, Sharp packages, peer links, and integrity metadata.
The root importer and the two existing package importers must not gain unrelated dependencies. The lockfile is generated by pnpm 11.16.0, never manually edited.
6. Strict POST /api/preflight request contract
The route is a Next Route Handler with runtime = "nodejs", no Edge runtime, no Server Action, and no caching.
Constants:
contractVersion: "0.1"
MAX_PREFLIGHT_REQUEST_BYTES: 65,536
MAX_PREFLIGHT_RESPONSE_BYTES: 2,097,152
size unit: UTF-8 bytes, not JavaScript string length
accepted media type: application/json with optional charset=utf-8
The request is a strict discriminated union. Every object uses Zod strictObject; unknown keys are rejected.
LIVE request:
{
"contractVersion": "0.1",
"mode": "LIVE",
"intent": "<value accepted by public IntentSchema>"
}
LIVE requires intent parsed only through public @moss-mini-demo/report-schemaIntentSchema; it forbids scenario.
FIXTURE requires one allowlisted scenario; it forbids caller-supplied intent because each reviewed Fixture owns its synthetic intent.
Both modes forbid caller-supplied runId, RPC URL, chain endpoint, credential, arbitrary fixture path, protocol-module name, or extra property.
Mode is case-sensitive and only LIVE | FIXTURE.
A claimed Content-Length above 65,536 bytes is rejected before reading. Missing or false-small Content-Length does not bypass the streaming byte counter.
The body reader stops and cancels when accumulated bytes exceed 65,536. It does not call an unbounded request.json() first.
Empty, malformed, non-object, array, prototype-sensitive, and strict-schema-invalid payloads are rejected without echoing input or Zod internals.
7. runId ownership and format
The server route generates one run identifier immediately on entry, before media-type/body/schema validation, so every success and structured error can be correlated.
apps/web/src/server/run-id.ts is the only generator and uses Node crypto.randomUUID(). The route creates it once, passes it read-only to the service, and returns the same value. A client cannot choose or overwrite it. A runId is transport correlation metadata, not reportId, provenance, evidence, authorization, or a replay/security token.
8. Strict POST response and HTTP contract
All response objects are strict, versioned, schema-validated before serialization, measured as UTF-8 bytes, and emitted with:
LIVE success permits only report provenance LIVE_SOURCE | LOCAL_FORK.
FIXTURE success:
{
"contractVersion": "0.1",
"ok": true,
"runId": "run_<uuid-v4>",
"mode": "FIXTURE",
"scenario": "manual-review-success",
"report": "<public PreflightReportSchema value with provenance FIXTURE>"
}
The returned scenario must equal the requested allowlisted scenario. The Fake service maps the three scenario identifiers only to the three existing read-only Fixture files:
Every Fixture is parsed through the public PreflightReportSchema before return. The Fake service does not copy, modify, repair, strengthen, or re-decide a Fixture.
Structured error:
{
"contractVersion": "0.1",
"ok": false,
"runId": "run_<uuid-v4>",
"error": {
"code": "INVALID_REQUEST",
"message": "Request does not match the preflight contract."
}
}
The error code/status mapping is frozen:
HTTP
Code
Condition
400
INVALID_JSON
Body is empty or not valid JSON
400
INVALID_REQUEST
Parsed JSON fails the strict request schema
413
REQUEST_TOO_LARGE
Declared or observed UTF-8 body exceeds 65,536 bytes
415
UNSUPPORTED_MEDIA_TYPE
Content-Type is absent or not accepted JSON
503
LIVE_UNAVAILABLE
Baseline Fake service receives a valid LIVE request
500
RESPONSE_TOO_LARGE
A schema-valid service result serializes above 2,097,152 bytes
500
INTERNAL_ERROR
Unexpected service/contract failure
Error messages are fixed, non-sensitive strings of at most 256 characters. They do not include payloads, Zod issues, stack traces, filesystem paths, RPC data, environment values, or secrets. An HTTP error never includes a report or Decision and never masquerades as STOP. An oversized success is not truncated and is not returned as partial evidence.
9. Fake service public contract
apps/web/src/server/preflight-service.ts is the stable server-only interface owned by Web/API:
The file imports server-only. Future #25-#31 packages do not modify this interface; Issue #33 (M2-12) later replaces/injects the orchestration implementation under its own Scope Gate.
The baseline FakePreflightService:
is synchronous in evidence selection and returns a Promise only to match the future service boundary;
performs no network, RPC, Moss, Decision Engine, wallet, filesystem-path input, signing, or transaction behavior;
returns validated synthetic reports for allowlisted FIXTURE scenarios;
returns LIVE_UNAVAILABLE for LIVE and never falls back to FIXTURE;
preserves Fixture provenance and Decision exactly;
does not generate runId or own HTTP status/headers;
does not mutate request or Fixture input.
apps/web/src/server/preflight-handler.ts owns HTTP parsing, limits, service invocation, response validation/size checking, and error mapping. The route file is a thin Node-runtime composition root. Tests may inject a contract-compatible service and runId generator into the handler factory; production uses the Fake service and real runId generator.
10. GET /api/health contract
GET /api/health returns HTTP 200, application/json; charset=utf-8, cache-control: no-store, and exactly:
The health route validates this value through the strict public HealthResponseSchema. It returns no timestamp, hostname, IP, RPC URL/host, environment-variable name/value, credential, token, key, wallet, address, filesystem path, error detail, request data, or live network probe. configured: false is status metadata, not evidence that a network check ran.
11. Server-only and browser boundary
The accepted dependency direction remains:
web/client -> client-safe Web contracts and report-schema contract only
web/server -> Web contracts and server service boundary
All files under apps/web/src/server begin with import "server-only". Both Route Handlers explicitly use Node runtime. No Client Component imports a server file, vendor/moss, Moss package, future moss-adapter, future preflight-core, server environment, or Clear402 module.
The minimal page is a static, non-interactive application placeholder only. It does not present Fixture output as live evidence and does not claim that a runnable integrated demo exists.
After production build, browser-bundle-leak.smoke.mjs recursively scans apps/web/.next/static. It fails on these case-insensitive markers:
The smoke also requires at least one static JS artifact and separately proves the server output contains the exact integration commit and @themoss/core marker. This makes the negative browser scan meaningful rather than passing because the server metadata was omitted.
No clear402-profile dependency or import is added. The health response's server-side clear402.enabled=false is status only and cannot alter Core behavior or evidence.
12. Tests and required coverage
apps/web/test/contracts.test.ts covers:
strict LIVE and FIXTURE positive parses;
public IntentSchema validation;
all three scenarios and rejection of every other value/path;
invalid/lowercase mode, extra keys, runId input, scenario-on-LIVE, intent-on-FIXTURE;
RunId positive/negative patterns;
strict success/error response branches and provenance/mode correlation;
preserved provenance: FIXTURE and exact Fixture Decision;
LIVE produces LIVE_UNAVAILABLE with no Fixture fallback;
repeated calls do not mutate request or Fixture data;
caller runId is preserved and not regenerated by the service.
apps/web/test/routes.test.ts covers:
health 200, headers, exact schema, and absence of secret/RPC/host material;
valid FIXTURE 200 response;
valid LIVE 503 without fallback;
unsupported media type 415;
invalid/empty JSON 400;
strict request error 400;
declared and streamed request overflow 413;
exact-boundary 65,536-byte handling;
oversized injected service response becomes small 500, never truncated;
unexpected service failure becomes redacted 500;
every response has one valid server-generated runId;
no request, error, stack, or environment echo.
apps/web/test/browser-bundle-leak.smoke.mjs runs only after production build and applies the server/static assertions above.
apps/web/test/production-start.smoke.mjs:
requires an existing production .next build;
allocates an available loopback port;
starts the root pnpm start path with NEXT_TELEMETRY_DISABLED=1;
waits no more than 30 seconds for GET /api/health;
requires HTTP 200, JSON content type, no-store, and the exact Health schema values;
terminates the one Next process with SIGTERM and allows 5 seconds for clean exit before failing and forcing cleanup;
exits nonzero on early process exit, timeout, contract mismatch, leak, or orphaned process.
The smoke binds only 127.0.0.1; it performs no external HTTP, RPC, protocol, wallet, or chain call.
13. Documentation corrections
The three authorized current-state documents receive minimal, stable facts:
the repository now contains a production-buildable/startable Web/API baseline and offline Fake service;
this is not the integrated demo, report orchestration, Moss/Monad/RPC/protocol behavior, or real backend evidence;
FIXTURE responses remain synthetic and visibly provenance: FIXTURE;
valid LIVE requests return LIVE_UNAVAILABLE in this baseline and never silently fall back;
no key, wallet, signing, transaction, secret, real address, or real-chain evidence is introduced;
MANUAL_REVIEW and STOP meanings are unchanged;
build, health, Fake service, and green CI are engineering evidence only, not safety guarantees.
docs/architecture.md, docs/security-boundary.md, ADRs, M1 evidence, and #23 Scope Cut documentation are not changed.
14. Implementation sequence after authorization
Re-fetch and verify exact origin/main. If it differs from 93235e5c3ef531075c860beadc6ad2ce6b3dc8a0, stop, scan the new main, and request a refreshed Scope Gate before branching.
Verify no open competing PR/worktree and create the planned branch in the planned isolated worktree.
Generate the lockfile only with Node 22.23.1 and pnpm 11.16.0; audit the importer, exact versions, integrities, peer links, Sharp build permission, and unexpected package scripts.
Implement client-safe contracts first.
Implement server-only Moss build metadata, RunId generator, HTTP byte helpers, public service interface, Fake implementation, and injectable handler.
Add thin Node Route Handlers and the minimal static App Router page/layout.
Add contract, Fake, route, bundle, and production-start tests.
Make only the three authorized stable documentation corrections.
Inspect the exact diff. Any path outside the 30-path list, dependency outside the fixed set, workflow need, or contract ambiguity stops implementation.
Run focused tests, clean production build/start/bundle smoke, full root quality gate, and exact diff checks.
Commit and push one branch, then create a Draft PR titled feat: add Web API baseline and strict contracts with Closes #32 only.
Wait for exact-Head quality-gate success, update the Implementation Report, add a Pre-PR QA handoff, freeze the head, and stop. Do not execute Review, Ready, Merge Gate, Merge, Issue/Project, permission, or protection operations.
15. Verification commands
Run from an isolated checkout with no node_modules, dist, .next, or untracked generated file. Keep the pinned Moss submodule unmodified; deinitialize it before the root Mini-Demo gate as established by #24.
The response must match the frozen health object exactly and contain no RPC URL, host, secret, or credential.
Before handoff, run a pushed-branch fresh-clone proof with a new local pnpm store, repeat frozen install/Web build/tests/smokes/pnpm check, and confirm the resulting worktree is clean apart from the reviewed 30-path commit diff.
16. Acceptance and exit conditions
Implementation is acceptable only when all are true:
exact Node, pnpm, Next, React, React DOM, Sharp, type, and server-only versions are locked;
frozen install succeeds from a clean store without an unapproved build script;
Sharp reports version 0.34.5;
standalone Web build/typecheck succeeds with no historical report-schema dist;
The Fake service and existing Fixtures are synthetic development tools. Production build/start, a health response, a strict API envelope, and green CI do not prove application correctness, protocol behavior, chain evidence, transaction safety, approval, authorization, execution, or permission to sign.
18. Risks and rollback
Framework/config mutation: Next may propose generated TypeScript changes. All expected files are predeclared; any extra or rewritten contract stops implementation.
Sharp supply chain/native build: only exact 0.34.5 is allowed to run a build script. Failure or extra build permission stops the task.
Server/client leakage: server metadata intentionally contains Moss/Clear402 markers; static output must not.
Fake/live confusion: Fake output is always FIXTURE; LIVE is explicitly unavailable and never downgraded.
Oversized evidence: responses are measured and rejected, never truncated or partially presented.
Run correlation: runId is server-generated transport metadata; clients must use it to reject stale UI responses later, but this issue adds no client state machine.
Root gate duration: production build/start smoke increases CI time but remains in the existing single pnpm check entry.
Rollback: revert the single M2-11: Create Web/API baseline and strict request contracts #32 implementation commit/PR. This removes apps/web, its workspace importer, scripts, Sharp allowlist, dependency graph, ignored build output, and the three current-state corrections together. No database, deployment, external service, secret, or user data exists to migrate or delete.
19. Requested Maintainer Scope Gate
Please record one of:
SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZED for the exact 30 paths, dependency set, package policy, request/response/health fields, sizes, runId, Fake service, server-only boundary, tests, and verification contract above; or
SCOPE_CHANGES_REQUESTED with the exact path, field, value, or ownership change required.
Reviewed Work Plan body SHA-256: 6e2a8e412f3d889ec58acfd719be474f06cafb8365872c43c02d7e304a31cab6
The 30-path boundary, strict/fail-closed API contracts, server-only ownership, production build/start smoke, browser-bundle leakage gate, and prohibition on real Moss, Decision orchestration, Clear402 behavior, RPC, wallet, signing, and chain evidence are otherwise coherent with #22 and #32.
One supply-chain scope blocker prevents implementation authorization:
Section 3 proposes allowBuilds: { sharp: true } while claiming that build permission is limited to exact sharp@0.34.5. Under pnpm 11, an unversioned sharp: true matcher approves build scripts for the registry package name without fixing the version. It therefore does not implement the stated minimum, version-pinned permission boundary. pnpm supports version-qualified package matchers: https://pnpm.io/settings/build#allowbuilds
Required Work Plan correction:
Freeze the workspace permission as exactly 'sharp@0.34.5': true; do not authorize the unversioned sharp matcher.
Update every plan, acceptance, audit, and rollback reference that currently describes allowBuilds.sharp so the version-qualified matcher is the normative value.
Retain exact direct dependency sharp: "0.34.5", the frozen lockfile resolution and integrity metadata, and the prohibition on any second build-script permission.
Keep the clean-store Node 22.23.1 / pnpm 11.16.0 install and Sharp import proof, and verify that no unreviewed build is reported or auto-added to pnpm-workspace.yaml.
No implementation is authorized from the current Work Plan. Submit a revised, closed Work Plan for a new Maintainer Scope Gate. Until SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZED is recorded, do not create the branch, worktree, commit, push, or PR.
#32 remains Open, assigned to Qy, and Project In Progress for planning only. This is not QA, Review, READY_TO_MERGE, or merge authorization.
Revised Final Implementation Work Plan v2 - Version-Pinned Sharp Build Permission - Awaiting Maintainer Scope Confirmation
This complete revised plan supersedes, but does not edit or delete, the original Work Plan. It responds only to the Maintainer's SCOPE_CHANGES_REQUESTED; both earlier comments remain immutable audit records.
Unique revision delta
The sole authorized allowBuilds key is now the version-qualified matcher 'sharp@0.34.5': true, replacing the unversioned sharp: true proposal.
The writable-path description, supply-chain acceptance, implementation sequence, verification, stop conditions, risks, and rollback language now make that exact matcher normative.
A second build-script permission is explicitly forbidden, and pnpm must not auto-add an unreviewed placeholder or any other matcher to pnpm-workspace.yaml.
The exact 30 writable paths, dependencies, API/health/Fake contracts, tests, documentation scope, non-goals, and all other implementation boundaries are unchanged. There is no second revision axis.
Planned branch after authorization: codex/issue-32-web-api-baseline.
Planned isolated worktree after authorization: /Users/qy/Documents/moss-mini-demo-issue-32.
This revised Work Plan is the complete implementation request. No branch, worktree, file, dependency, lockfile, commit, push, deployment, or PR may be created before a Maintainer records explicit SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZED.
2. Goal and delivery boundary
Build a production-buildable and production-startable Next.js App Router skeleton on the accepted Node runtime, with:
strict and versioned POST /api/preflight request/response contracts;
strict GET /api/health response fields;
fixed request and response byte limits;
server-generated run identifiers;
an offline Fake service implementing the same server service interface later used by real orchestration;
exact fixture scenario allowlisting;
explicit server-only ownership;
automated production start/health and browser-bundle leakage smoke tests.
This issue creates an application/API baseline, not an integrated demo. It does not implement Moss orchestration, Quote collection, Capability construction, simulation, Alignment, Decision Engine orchestration, report assembly, Monad/RPC access, Clear402 behavior, wallet behavior, signing, or transaction submission.
No caret, tilde, tag, floating version, or additional dependency is authorized. The existing root TypeScript 7.0.2, Vitest 4.1.10, and Biome 2.5.5 remain the only compiler/test/format toolchain.
sharp@0.34.5 is a reviewed direct runtime dependency because Next production image handling resolves it and its install script must not be silently blocked or broadly enabled. pnpm-workspace.yaml will contain exactly:
The version-qualified matcher 'sharp@0.34.5' is the normative build-script permission and the only key permitted under allowBuilds. The unversioned matcher sharp: true, dangerouslyAllowAllBuilds, wildcard build permission, ignored-build bypass, and any second build-script permission are forbidden. pnpm must not automatically add an unreviewed placeholder, package matcher, or approval entry to pnpm-workspace.yaml; any such mutation stops implementation. The lockfile must resolve Sharp exactly to 0.34.5 and retain package integrity metadata. A clean-store install must prove the reviewed Sharp script succeeds, pnpm ignored-builds must report no unreviewed build requiring a new permission, and a Node import must report Sharp 0.34.5.
4. Closed writable path list
Exactly these 30 repository paths are writable:
.gitignore - ignore Next build output only.
package.json - add exact root web scripts/order; do not change existing dependency versions.
pnpm-lock.yaml - generated frozen dependency graph and one apps/web importer only.
pnpm-workspace.yaml - register apps/* and contain exactly one build-script permission: the version-qualified matcher 'sharp@0.34.5': true; no unversioned matcher, second permission, or pnpm-added placeholder.
tsconfig.json - keep root strict checking but delegate apps/web to its own Next config.
README.md - minimal stable current-state correction for the Web/API baseline.
SECURITY.md - minimal stable boundary correction; no weakening of exclusions.
docs/real-vs-mock.md - identify the Fake service and Fixtures as synthetic/non-evidence.
apps/web/package.json
apps/web/tsconfig.json
apps/web/next-env.d.ts
apps/web/next.config.ts
apps/web/app/globals.css
apps/web/app/layout.tsx
apps/web/app/page.tsx
apps/web/app/api/health/route.ts
apps/web/app/api/preflight/route.ts
apps/web/src/contracts/health.ts
apps/web/src/contracts/preflight.ts
apps/web/src/server/moss-build-info.ts
apps/web/src/server/run-id.ts
apps/web/src/server/http-json.ts
apps/web/src/server/preflight-service.ts
apps/web/src/server/fake-preflight-service.ts
apps/web/src/server/preflight-handler.ts
apps/web/test/contracts.test.ts
apps/web/test/fake-preflight-service.test.ts
apps/web/test/routes.test.ts
apps/web/test/browser-bundle-leak.smoke.mjs
apps/web/test/production-start.smoke.mjs
There is no wildcard writable path. No generated asset, snapshot, public directory, fixture, application package, or 31st path may be added. In particular, this issue must not modify .github/workflows/quality-gate.yml, .gitmodules, vendor/moss, any packages/report-schema or packages/decision-engine file, any ADR, docs/architecture.md, docs/security-boundary.md, or STOP presentation rules.
5. Workspace, build, and script contract
.gitignore adds .next/. No source path is ignored.
The root tsconfig.json continues strict no-emit validation for existing root/package code and excludes apps/**; apps/web/tsconfig.json owns DOM, JSX, Next plugin, JSON-module, incremental, and generated Next type settings. The committed next-env.d.ts uses only stable Next type references and does not import a missing .next artifact, so zero-artifact typecheck remains valid. Root typecheck must explicitly invoke the Web package typecheck so exclusion cannot become a coverage gap.
Root scripts retain the existing gate and use these exact semantics:
dev: next dev
start: next start
build: build @moss-mini-demo/report-schema, then next build
typecheck: build @moss-mini-demo/report-schema, then tsc --noEmit
The public report package is built first so pnpm --filter @moss-mini-demo/web build and Web typecheck work in a clean checkout with no pre-existing dist. No TypeScript path alias to package-private source, committed dist, hidden lifecycle script, or postinstall hook is permitted. Test code cannot invoke a build; the existing root test script keeps its explicit build prerequisite visible.
pnpm-lock.yaml changes are limited to:
the new apps/web importer;
the exact direct dependencies listed above;
their pnpm-resolved transitive graph, platform-specific Next SWC packages, Sharp packages, peer links, and integrity metadata.
The root importer and the two existing package importers must not gain unrelated dependencies. The lockfile is generated by pnpm 11.16.0, never manually edited. Build-script permission remains solely in pnpm-workspace.yaml as 'sharp@0.34.5': true; it must not be duplicated, generalized, or represented by a generated placeholder.
6. Strict POST /api/preflight request contract
The route is a Next Route Handler with runtime = "nodejs", no Edge runtime, no Server Action, and no caching.
Constants:
contractVersion: "0.1"
MAX_PREFLIGHT_REQUEST_BYTES: 65,536
MAX_PREFLIGHT_RESPONSE_BYTES: 2,097,152
size unit: UTF-8 bytes, not JavaScript string length
accepted media type: application/json with optional charset=utf-8
The request is a strict discriminated union. Every object uses Zod strictObject; unknown keys are rejected.
LIVE request:
{
"contractVersion": "0.1",
"mode": "LIVE",
"intent": "<value accepted by public IntentSchema>"
}
LIVE requires intent parsed only through public @moss-mini-demo/report-schemaIntentSchema; it forbids scenario.
FIXTURE requires one allowlisted scenario; it forbids caller-supplied intent because each reviewed Fixture owns its synthetic intent.
Both modes forbid caller-supplied runId, RPC URL, chain endpoint, credential, arbitrary fixture path, protocol-module name, or extra property.
Mode is case-sensitive and only LIVE | FIXTURE.
A claimed Content-Length above 65,536 bytes is rejected before reading. Missing or false-small Content-Length does not bypass the streaming byte counter.
The body reader stops and cancels when accumulated bytes exceed 65,536. It does not call an unbounded request.json() first.
Empty, malformed, non-object, array, prototype-sensitive, and strict-schema-invalid payloads are rejected without echoing input or Zod internals.
7. runId ownership and format
The server route generates one run identifier immediately on entry, before media-type/body/schema validation, so every success and structured error can be correlated.
apps/web/src/server/run-id.ts is the only generator and uses Node crypto.randomUUID(). The route creates it once, passes it read-only to the service, and returns the same value. A client cannot choose or overwrite it. A runId is transport correlation metadata, not reportId, provenance, evidence, authorization, or a replay/security token.
8. Strict POST response and HTTP contract
All response objects are strict, versioned, schema-validated before serialization, measured as UTF-8 bytes, and emitted with:
LIVE success permits only report provenance LIVE_SOURCE | LOCAL_FORK.
FIXTURE success:
{
"contractVersion": "0.1",
"ok": true,
"runId": "run_<uuid-v4>",
"mode": "FIXTURE",
"scenario": "manual-review-success",
"report": "<public PreflightReportSchema value with provenance FIXTURE>"
}
The returned scenario must equal the requested allowlisted scenario. The Fake service maps the three scenario identifiers only to the three existing read-only Fixture files:
Every Fixture is parsed through the public PreflightReportSchema before return. The Fake service does not copy, modify, repair, strengthen, or re-decide a Fixture.
Structured error:
{
"contractVersion": "0.1",
"ok": false,
"runId": "run_<uuid-v4>",
"error": {
"code": "INVALID_REQUEST",
"message": "Request does not match the preflight contract."
}
}
The error code/status mapping is frozen:
HTTP
Code
Condition
400
INVALID_JSON
Body is empty or not valid JSON
400
INVALID_REQUEST
Parsed JSON fails the strict request schema
413
REQUEST_TOO_LARGE
Declared or observed UTF-8 body exceeds 65,536 bytes
415
UNSUPPORTED_MEDIA_TYPE
Content-Type is absent or not accepted JSON
503
LIVE_UNAVAILABLE
Baseline Fake service receives a valid LIVE request
500
RESPONSE_TOO_LARGE
A schema-valid service result serializes above 2,097,152 bytes
500
INTERNAL_ERROR
Unexpected service/contract failure
Error messages are fixed, non-sensitive strings of at most 256 characters. They do not include payloads, Zod issues, stack traces, filesystem paths, RPC data, environment values, or secrets. An HTTP error never includes a report or Decision and never masquerades as STOP. An oversized success is not truncated and is not returned as partial evidence.
9. Fake service public contract
apps/web/src/server/preflight-service.ts is the stable server-only interface owned by Web/API:
The file imports server-only. Future #25-#31 packages do not modify this interface; Issue #33 (M2-12) later replaces/injects the orchestration implementation under its own Scope Gate.
The baseline FakePreflightService:
is synchronous in evidence selection and returns a Promise only to match the future service boundary;
performs no network, RPC, Moss, Decision Engine, wallet, filesystem-path input, signing, or transaction behavior;
returns validated synthetic reports for allowlisted FIXTURE scenarios;
returns LIVE_UNAVAILABLE for LIVE and never falls back to FIXTURE;
preserves Fixture provenance and Decision exactly;
does not generate runId or own HTTP status/headers;
does not mutate request or Fixture input.
apps/web/src/server/preflight-handler.ts owns HTTP parsing, limits, service invocation, response validation/size checking, and error mapping. The route file is a thin Node-runtime composition root. Tests may inject a contract-compatible service and runId generator into the handler factory; production uses the Fake service and real runId generator.
10. GET /api/health contract
GET /api/health returns HTTP 200, application/json; charset=utf-8, cache-control: no-store, and exactly:
The health route validates this value through the strict public HealthResponseSchema. It returns no timestamp, hostname, IP, RPC URL/host, environment-variable name/value, credential, token, key, wallet, address, filesystem path, error detail, request data, or live network probe. configured: false is status metadata, not evidence that a network check ran.
11. Server-only and browser boundary
The accepted dependency direction remains:
web/client -> client-safe Web contracts and report-schema contract only
web/server -> Web contracts and server service boundary
All files under apps/web/src/server begin with import "server-only". Both Route Handlers explicitly use Node runtime. No Client Component imports a server file, vendor/moss, Moss package, future moss-adapter, future preflight-core, server environment, or Clear402 module.
The minimal page is a static, non-interactive application placeholder only. It does not present Fixture output as live evidence and does not claim that a runnable integrated demo exists.
After production build, browser-bundle-leak.smoke.mjs recursively scans apps/web/.next/static. It fails on these case-insensitive markers:
The smoke also requires at least one static JS artifact and separately proves the server output contains the exact integration commit and @themoss/core marker. This makes the negative browser scan meaningful rather than passing because the server metadata was omitted.
No clear402-profile dependency or import is added. The health response's server-side clear402.enabled=false is status only and cannot alter Core behavior or evidence.
12. Tests and required coverage
apps/web/test/contracts.test.ts covers:
strict LIVE and FIXTURE positive parses;
public IntentSchema validation;
all three scenarios and rejection of every other value/path;
invalid/lowercase mode, extra keys, runId input, scenario-on-LIVE, intent-on-FIXTURE;
RunId positive/negative patterns;
strict success/error response branches and provenance/mode correlation;
preserved provenance: FIXTURE and exact Fixture Decision;
LIVE produces LIVE_UNAVAILABLE with no Fixture fallback;
repeated calls do not mutate request or Fixture data;
caller runId is preserved and not regenerated by the service.
apps/web/test/routes.test.ts covers:
health 200, headers, exact schema, and absence of secret/RPC/host material;
valid FIXTURE 200 response;
valid LIVE 503 without fallback;
unsupported media type 415;
invalid/empty JSON 400;
strict request error 400;
declared and streamed request overflow 413;
exact-boundary 65,536-byte handling;
oversized injected service response becomes small 500, never truncated;
unexpected service failure becomes redacted 500;
every response has one valid server-generated runId;
no request, error, stack, or environment echo.
apps/web/test/browser-bundle-leak.smoke.mjs runs only after production build and applies the server/static assertions above.
apps/web/test/production-start.smoke.mjs:
requires an existing production .next build;
allocates an available loopback port;
starts the root pnpm start path with NEXT_TELEMETRY_DISABLED=1;
waits no more than 30 seconds for GET /api/health;
requires HTTP 200, JSON content type, no-store, and the exact Health schema values;
terminates the one Next process with SIGTERM and allows 5 seconds for clean exit before failing and forcing cleanup;
exits nonzero on early process exit, timeout, contract mismatch, leak, or orphaned process.
The smoke binds only 127.0.0.1; it performs no external HTTP, RPC, protocol, wallet, or chain call.
13. Documentation corrections
The three authorized current-state documents receive minimal, stable facts:
the repository now contains a production-buildable/startable Web/API baseline and offline Fake service;
this is not the integrated demo, report orchestration, Moss/Monad/RPC/protocol behavior, or real backend evidence;
FIXTURE responses remain synthetic and visibly provenance: FIXTURE;
valid LIVE requests return LIVE_UNAVAILABLE in this baseline and never silently fall back;
no key, wallet, signing, transaction, secret, real address, or real-chain evidence is introduced;
MANUAL_REVIEW and STOP meanings are unchanged;
build, health, Fake service, and green CI are engineering evidence only, not safety guarantees.
docs/architecture.md, docs/security-boundary.md, ADRs, M1 evidence, and #23 Scope Cut documentation are not changed.
14. Implementation sequence after authorization
Re-fetch and verify exact origin/main. If it differs from 93235e5c3ef531075c860beadc6ad2ce6b3dc8a0, stop, scan the new main, and request a refreshed Scope Gate before branching.
Verify no open competing PR/worktree and create the planned branch in the planned isolated worktree.
Set the sole allowBuilds entry to the exact matcher 'sharp@0.34.5': true, then generate the lockfile only with Node 22.23.1 and pnpm 11.16.0; audit the importer, exact versions, integrities, peer links, unexpected package scripts, and pnpm ignored-builds. Confirm pnpm did not add an unreviewed placeholder or second permission to pnpm-workspace.yaml.
Implement client-safe contracts first.
Implement server-only Moss build metadata, RunId generator, HTTP byte helpers, public service interface, Fake implementation, and injectable handler.
Add thin Node Route Handlers and the minimal static App Router page/layout.
Add contract, Fake, route, bundle, and production-start tests.
Make only the three authorized stable documentation corrections.
Inspect the exact diff. Any path outside the 30-path list, dependency outside the fixed set, workflow need, contract ambiguity, unversioned Sharp permission, second build-script permission, or pnpm-added placeholder stops implementation.
Run focused tests, clean production build/start/bundle smoke, full root quality gate, and exact diff checks.
Commit and push one branch, then create a Draft PR titled feat: add Web API baseline and strict contracts with Closes #32 only.
Wait for exact-Head quality-gate success, update the Implementation Report, add a Pre-PR QA handoff, freeze the head, and stop. Do not execute Review, Ready, Merge Gate, Merge, Issue/Project, permission, or protection operations.
15. Verification commands
Run from an isolated checkout with no node_modules, dist, .next, or untracked generated file. Keep the pinned Moss submodule unmodified; deinitialize it before the root Mini-Demo gate as established by #24.
The response must match the frozen health object exactly and contain no RPC URL, host, secret, or credential.
Before handoff, run a pushed-branch fresh-clone proof with a new local pnpm store, repeat frozen install/Web build/tests/smokes/pnpm check, and confirm the resulting worktree is clean apart from the reviewed 30-path commit diff. In both isolated installs, pnpm config get allowBuilds --json must resolve semantically to exactly {"sharp@0.34.5":true}, pnpm ignored-builds must identify no unreviewed build requiring another permission, and the pre/post-install workspace-policy hashes must match so pnpm cannot silently add a placeholder.
16. Acceptance and exit conditions
Implementation is acceptable only when all are true:
exact Node, pnpm, Next, React, React DOM, Sharp, type, and server-only versions are locked, and the sole build-script permission is the version-qualified matcher 'sharp@0.34.5': true;
frozen install succeeds from a clean store without an unapproved build script, second permission, unversioned Sharp matcher, or pnpm-added placeholder;
Sharp reports version 0.34.5;
standalone Web build/typecheck succeeds with no historical report-schema dist;
next build, one-process next start, loopback health smoke, browser leakage scan, and full pnpm check pass;
pnpm and Next do not rewrite pnpm-workspace.yaml, tsconfig.json, apps/web/tsconfig.json, next-env.d.ts, package manifests, or lockfile during install/build;
apps/web/.next/static contains no forbidden Moss/Clear402/server marker while server output contains the expected pinned metadata;
no Fixture is labeled LIVE and no HTTP/programming error is represented as a Decision;
exact diff contains only the 30 listed paths;
exact-Head CI uses the unchanged quality-gate job and succeeds;
PR remains Draft and is handed to Pre-PR QA.
Stop without opening or updating a PR if:
main baseline changes before branching;
any contract field or semantic remains unresolved;
Next requires another dependency, config, generated tracked file, Edge runtime, or workflow change;
pnpm resolves a different direct version, uses an unversioned Sharp matcher, reports an unreviewed build, or adds a placeholder or second build-script permission;
Sharp install/import fails on Node 22.23.1;
public report-schema imports cannot be used without a private source path;
a Fixture fails public schema validation or Fake output would require mutation;
LIVE would need to fall back to FIXTURE;
response limiting would require truncating evidence;
browser leakage or production smoke cannot pass;
any 31st path is needed.
A stop returns SCOPE_CHANGES_REQUESTED; it does not authorize a workaround.
17. Non-goals and trust boundaries
No implementation of:
real Moss package import or execution in app code;
The Fake service and existing Fixtures are synthetic development tools. Production build/start, a health response, a strict API envelope, and green CI do not prove application correctness, protocol behavior, chain evidence, transaction safety, approval, authorization, execution, or permission to sign.
18. Risks and rollback
Framework/config mutation: Next may propose generated TypeScript changes. All expected files are predeclared; any extra or rewritten contract stops implementation.
Sharp supply chain/native build: only the exact version-qualified matcher 'sharp@0.34.5': true may authorize a build script. An unversioned matcher, install/import failure, ignored unreviewed build, or extra permission stops the task.
Server/client leakage: server metadata intentionally contains Moss/Clear402 markers; static output must not.
Fake/live confusion: Fake output is always FIXTURE; LIVE is explicitly unavailable and never downgraded.
Oversized evidence: responses are measured and rejected, never truncated or partially presented.
Run correlation: runId is server-generated transport metadata; clients must use it to reject stale UI responses later, but this issue adds no client state machine.
Root gate duration: production build/start smoke increases CI time but remains in the existing single pnpm check entry.
Automatic policy mutation: pnpm must not add an approval placeholder or matcher during install. The pre/post-install pnpm-workspace.yaml hash, structured config output, ignored-build report, and exact diff make any mutation a hard stop.
Rollback: revert the single M2-11: Create Web/API baseline and strict request contracts #32 implementation commit/PR. This removes apps/web, its workspace importer, scripts, the exact 'sharp@0.34.5': true permission, dependency graph, ignored build output, and the three current-state corrections together. No database, deployment, external service, secret, or user data exists to migrate or delete.
19. Requested Maintainer Scope Gate
Please record one of:
SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZED for the exact 30 paths, dependency set, sole version-qualified 'sharp@0.34.5': true build permission, prohibition on any second permission or pnpm-added placeholder, request/response/health fields, sizes, runId, Fake service, server-only boundary, tests, and verification contract above; or
SCOPE_CHANGES_REQUESTED with the exact path, field, value, or ownership change required.
Authorized Work Plan body SHA-256: 9b950740ed7008f89c4801a02c80624892ea38c7ae34e4aa58283c1d97b14561
Maintainer Scope Gate result: PASS.
The revised Work Plan is authorized with these frozen boundaries:
exactly the 30 writable repository paths enumerated in the revised Work Plan; no wildcard or 31st path;
exactly the listed runtime, application, type, and workspace dependencies, with no additional dependency or package permission;
exactly one allowBuilds entry: 'sharp@0.34.5': true; the unversioned Sharp matcher, any second matcher, any pnpm-added placeholder, and any broader build-script permission are forbidden;
the strict and fail-closed request, response, health, byte-limit, runId, Fixture allowlist, Fake service, and server-only contracts recorded in the revised Work Plan;
the specified contract, route, Fake-service, production build/start/health, browser-bundle leakage, clean-store, package-policy, and full quality-gate verification matrix;
no real Moss execution, Decision orchestration, Clear402 behavior, RPC, wallet, signing, transaction submission, live-chain evidence, Schema/Engine/ADR change, workflow change, or protection/permission change.
The original Work Plan remains an unchanged audit record. The revised plan is a separate comment and the only authorized implementation source.
Builder Qy may now re-fetch and confirm the exact baseline, then create only the planned codex/issue-32-web-api-baseline branch and isolated worktree, implement the authorized scope, and open one Draft PR with Closes #32 only. If main changes before branching, or implementation needs another path, dependency, build permission, public contract, workflow, or scope, stop and request a new Maintainer Scope Gate.
This record authorizes implementation only. It is not Pre-PR QA, an independent review, READY_TO_MERGE, Merge Gate, or merge authorization. The implementation PR must remain Draft until its exact-head QA handoff and subsequent Maintainer review.
#32 remains Open, assigned to pillowtalk-Qy, and Project In Progress. No downstream Issue is released by this authorization.
Activity
pillowtalk-Qy commentedon Jul 31, 2026
Dependency gate cleared - 2026-07-31
M2-01 / #22 is Maintainer Accepted and closed. Its compatibility spike established:
22.23.1and pnpm11.10.0;16.2.12with React/React DOM19.2.3;next start;CLEAR402_ENABLEDabsent/false returning an independent disabled path.#32 is released from Blocked to Ready.
Implementation boundaries:
sharp@0.34.5; any build-script allowlist entry must be explicit, reviewed, pinned, and documented. Do not bypass pnpm supply-chain policy.This record authorizes Ready status only; it does not approve a skeleton diff or production Gate.
pillowtalk-Qy commentedon Aug 5, 2026
M2_EXECUTION_SLOT_ASSIGNED
Builder:
pillowtalk-QyPlanning baseline:
origin/main@93235e5c3ef531075c860beadc6ad2ce6b3dc8a0Upstream execution-slot evidence:
Issue #32 is now the single active Builder slot and is moved to Project In Progress for planning.
Planned branch name after scope confirmation:
codex/issue-32-web-api-baselinePlanned isolated worktree after scope confirmation:
/Users/qy/Documents/moss-mini-demo-issue-32The first required evidence is a closed, path-specific Work Plan that freezes exact framework versions, writable paths, public/server boundaries, strict request and health contracts, Fake service contract, production build/start smoke, tests, and dependency changes.
In Progress starts planning only. It is not SCOPE_CONFIRMED, implementation authorization, QA PASS, Review, Merge Gate, or merge authorization. No branch, worktree, file modification, dependency update, commit, push, or PR may begin before Maintainer scope confirmation.
Issue #23 and newly released #25 remain Ready and unassigned. Other M2 Issues retain their existing blocked dependency gates.
pillowtalk-Qy commentedon Aug 5, 2026
Final Implementation Work Plan - Web/API Baseline and Strict Contracts - Awaiting Maintainer Scope Confirmation
1. Planning control
main@93235e5c3ef531075c860beadc6ad2ce6b3dc8a0.PLANNING_ONLY / AWAITING_MAINTAINER_SCOPE_CONFIRMATION.codex/issue-32-web-api-baseline./Users/qy/Documents/moss-mini-demo-issue-32.SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZED.2. Goal and delivery boundary
Build a production-buildable and production-startable Next.js App Router skeleton on the accepted Node runtime, with:
POST /api/preflightrequest/response contracts;GET /api/healthresponse fields;This issue creates an application/API baseline, not an integrated demo. It does not implement Moss orchestration, Quote collection, Capability construction, simulation, Alignment, Decision Engine orchestration, report assembly, Monad/RPC access, Clear402 behavior, wallet behavior, signing, or transaction submission.
3. Frozen runtime and dependency set
Runtime and package manager:
The new
apps/web/package.jsondependency set is exact:{ "dependencies": { "@moss-mini-demo/report-schema": "workspace:*", "next": "16.2.12", "react": "19.2.3", "react-dom": "19.2.3", "server-only": "0.0.1", "sharp": "0.34.5", "zod": "4.4.3" }, "devDependencies": { "@types/node": "22.20.0", "@types/react": "19.2.18", "@types/react-dom": "19.2.4" } }No caret, tilde, tag, floating version, or additional dependency is authorized. The existing root TypeScript
7.0.2, Vitest4.1.10, and Biome2.5.5remain the only compiler/test/format toolchain.sharp@0.34.5is a reviewed direct runtime dependency because Next production image handling resolves it and its install script must not be silently blocked or broadly enabled.pnpm-workspace.yamlwill contain exactly:No
dangerouslyAllowAllBuilds, wildcard build permission, ignored-build bypass, or second build-script allowlist entry is authorized. The lockfile must resolve Sharp exactly to0.34.5and retain package integrity metadata. A clean-store install must prove the reviewed Sharp script succeeds, and a Node import must report Sharp0.34.5.4. Closed writable path list
Exactly these 30 repository paths are writable:
.gitignore- ignore Next build output only.package.json- add exact root web scripts/order; do not change existing dependency versions.pnpm-lock.yaml- generated frozen dependency graph and oneapps/webimporter only.pnpm-workspace.yaml- registerapps/*and allow only the pinned Sharp build script.tsconfig.json- keep root strict checking but delegateapps/webto its own Next config.README.md- minimal stable current-state correction for the Web/API baseline.SECURITY.md- minimal stable boundary correction; no weakening of exclusions.docs/real-vs-mock.md- identify the Fake service and Fixtures as synthetic/non-evidence.apps/web/package.jsonapps/web/tsconfig.jsonapps/web/next-env.d.tsapps/web/next.config.tsapps/web/app/globals.cssapps/web/app/layout.tsxapps/web/app/page.tsxapps/web/app/api/health/route.tsapps/web/app/api/preflight/route.tsapps/web/src/contracts/health.tsapps/web/src/contracts/preflight.tsapps/web/src/server/moss-build-info.tsapps/web/src/server/run-id.tsapps/web/src/server/http-json.tsapps/web/src/server/preflight-service.tsapps/web/src/server/fake-preflight-service.tsapps/web/src/server/preflight-handler.tsapps/web/test/contracts.test.tsapps/web/test/fake-preflight-service.test.tsapps/web/test/routes.test.tsapps/web/test/browser-bundle-leak.smoke.mjsapps/web/test/production-start.smoke.mjsThere is no wildcard writable path. No generated asset, snapshot, public directory, fixture, application package, or 31st path may be added. In particular, this issue must not modify
.github/workflows/quality-gate.yml,.gitmodules,vendor/moss, anypackages/report-schemaorpackages/decision-enginefile, any ADR,docs/architecture.md,docs/security-boundary.md, or STOP presentation rules.5. Workspace, build, and script contract
.gitignoreadds.next/. No source path is ignored.The root
tsconfig.jsoncontinues strict no-emit validation for existing root/package code and excludesapps/**;apps/web/tsconfig.jsonowns DOM, JSX, Next plugin, JSON-module, incremental, and generated Next type settings. The committednext-env.d.tsuses only stable Next type references and does not import a missing.nextartifact, so zero-artifact typecheck remains valid. Roottypecheckmust explicitly invoke the Web package typecheck so exclusion cannot become a coverage gap.Root scripts retain the existing gate and use these exact semantics:
The Web package scripts are fixed as:
The public report package is built first so
pnpm --filter @moss-mini-demo/web buildand Web typecheck work in a clean checkout with no pre-existingdist. No TypeScript path alias to package-private source, committeddist, hidden lifecycle script, or postinstall hook is permitted. Test code cannot invoke a build; the existing roottestscript keeps its explicit build prerequisite visible.pnpm-lock.yamlchanges are limited to:apps/webimporter;The root importer and the two existing package importers must not gain unrelated dependencies. The lockfile is generated by pnpm
11.16.0, never manually edited.6. Strict POST /api/preflight request contract
The route is a Next Route Handler with
runtime = "nodejs", no Edge runtime, no Server Action, and no caching.Constants:
The request is a strict discriminated union. Every object uses Zod
strictObject; unknown keys are rejected.LIVE request:
{ "contractVersion": "0.1", "mode": "LIVE", "intent": "<value accepted by public IntentSchema>" }FIXTURE request:
{ "contractVersion": "0.1", "mode": "FIXTURE", "scenario": "manual-review-success" }The exact fixture scenario allowlist is:
Rules:
intentparsed only through public@moss-mini-demo/report-schemaIntentSchema; it forbidsscenario.scenario; it forbids caller-suppliedintentbecause each reviewed Fixture owns its synthetic intent.runId, RPC URL, chain endpoint, credential, arbitrary fixture path, protocol-module name, or extra property.LIVE | FIXTURE.Content-Lengthabove 65,536 bytes is rejected before reading. Missing or false-smallContent-Lengthdoes not bypass the streaming byte counter.request.json()first.7. runId ownership and format
The server route generates one run identifier immediately on entry, before media-type/body/schema validation, so every success and structured error can be correlated.
The format is:
apps/web/src/server/run-id.tsis the only generator and uses Nodecrypto.randomUUID(). The route creates it once, passes it read-only to the service, and returns the same value. A client cannot choose or overwrite it. A runId is transport correlation metadata, notreportId, provenance, evidence, authorization, or a replay/security token.8. Strict POST response and HTTP contract
All response objects are strict, versioned, schema-validated before serialization, measured as UTF-8 bytes, and emitted with:
Success is a strict mode-correlated union.
LIVE success:
{ "contractVersion": "0.1", "ok": true, "runId": "run_<uuid-v4>", "mode": "LIVE", "report": "<public PreflightReportSchema value>" }LIVE success permits only report provenance
LIVE_SOURCE | LOCAL_FORK.FIXTURE success:
{ "contractVersion": "0.1", "ok": true, "runId": "run_<uuid-v4>", "mode": "FIXTURE", "scenario": "manual-review-success", "report": "<public PreflightReportSchema value with provenance FIXTURE>" }The returned scenario must equal the requested allowlisted scenario. The Fake service maps the three scenario identifiers only to the three existing read-only Fixture files:
Every Fixture is parsed through the public
PreflightReportSchemabefore return. The Fake service does not copy, modify, repair, strengthen, or re-decide a Fixture.Structured error:
{ "contractVersion": "0.1", "ok": false, "runId": "run_<uuid-v4>", "error": { "code": "INVALID_REQUEST", "message": "Request does not match the preflight contract." } }The error code/status mapping is frozen:
INVALID_JSONINVALID_REQUESTREQUEST_TOO_LARGEUNSUPPORTED_MEDIA_TYPELIVE_UNAVAILABLERESPONSE_TOO_LARGEINTERNAL_ERRORError messages are fixed, non-sensitive strings of at most 256 characters. They do not include payloads, Zod issues, stack traces, filesystem paths, RPC data, environment values, or secrets. An HTTP error never includes a report or Decision and never masquerades as
STOP. An oversized success is not truncated and is not returned as partial evidence.9. Fake service public contract
apps/web/src/server/preflight-service.tsis the stable server-only interface owned by Web/API:The file imports
server-only. Future #25-#31 packages do not modify this interface; Issue #33 (M2-12) later replaces/injects the orchestration implementation under its own Scope Gate.The baseline
FakePreflightService:LIVE_UNAVAILABLEfor LIVE and never falls back to FIXTURE;apps/web/src/server/preflight-handler.tsowns HTTP parsing, limits, service invocation, response validation/size checking, and error mapping. The route file is a thin Node-runtime composition root. Tests may inject a contract-compatible service and runId generator into the handler factory; production uses the Fake service and real runId generator.10. GET /api/health contract
GET /api/healthreturns HTTP 200,application/json; charset=utf-8,cache-control: no-store, and exactly:{ "contractVersion": "0.1", "status": "ok", "app": { "name": "moss-mini-demo", "version": "0.0.0", "runtime": "nodejs", "nodeVersion": "22.23.1" }, "moss": { "sourceMode": "INTEGRATION_FORK", "upstreamCommit": "1ae6b6322d51fae9104f047efb94e601050b967f", "integrationCommit": "1ae6b6322d51fae9104f047efb94e601050b967f", "officialRelease": false, "packages": { "@themoss/core": "0.1.0", "@themoss/simulator": "0.1.0", "@themoss/protocol-kuru": "0.1.0", "@themoss/protocol-pancakeswap": "0.1.0" } }, "network": { "configured": false, "id": null }, "clear402": { "enabled": false } }The health route validates this value through the strict public
HealthResponseSchema. It returns no timestamp, hostname, IP, RPC URL/host, environment-variable name/value, credential, token, key, wallet, address, filesystem path, error detail, request data, or live network probe.configured: falseis status metadata, not evidence that a network check ran.11. Server-only and browser boundary
The accepted dependency direction remains:
All files under
apps/web/src/serverbegin withimport "server-only". Both Route Handlers explicitly use Node runtime. No Client Component imports a server file,vendor/moss, Moss package, futuremoss-adapter, futurepreflight-core, server environment, or Clear402 module.The minimal page is a static, non-interactive application placeholder only. It does not present Fixture output as live evidence and does not claim that a runnable integrated demo exists.
After production build,
browser-bundle-leak.smoke.mjsrecursively scansapps/web/.next/static. It fails on these case-insensitive markers:The smoke also requires at least one static JS artifact and separately proves the server output contains the exact integration commit and
@themoss/coremarker. This makes the negative browser scan meaningful rather than passing because the server metadata was omitted.No
clear402-profiledependency or import is added. The health response's server-sideclear402.enabled=falseis status only and cannot alter Core behavior or evidence.12. Tests and required coverage
apps/web/test/contracts.test.tscovers:IntentSchemavalidation;apps/web/test/fake-preflight-service.test.tscovers:PreflightReportSchemaacceptance;provenance: FIXTUREand exact Fixture Decision;LIVE_UNAVAILABLEwith no Fixture fallback;apps/web/test/routes.test.tscovers:apps/web/test/browser-bundle-leak.smoke.mjsruns only after production build and applies the server/static assertions above.apps/web/test/production-start.smoke.mjs:.nextbuild;pnpm startpath withNEXT_TELEMETRY_DISABLED=1;GET /api/health;The smoke binds only
127.0.0.1; it performs no external HTTP, RPC, protocol, wallet, or chain call.13. Documentation corrections
The three authorized current-state documents receive minimal, stable facts:
provenance: FIXTURE;LIVE_UNAVAILABLEin this baseline and never silently fall back;MANUAL_REVIEWandSTOPmeanings are unchanged;docs/architecture.md,docs/security-boundary.md, ADRs, M1 evidence, and #23 Scope Cut documentation are not changed.14. Implementation sequence after authorization
origin/main. If it differs from93235e5c3ef531075c860beadc6ad2ce6b3dc8a0, stop, scan the new main, and request a refreshed Scope Gate before branching.22.23.1and pnpm11.16.0; audit the importer, exact versions, integrities, peer links, Sharp build permission, and unexpected package scripts.feat: add Web API baseline and strict contractswithCloses #32only.quality-gatesuccess, update the Implementation Report, add a Pre-PR QA handoff, freeze the head, and stop. Do not execute Review, Ready, Merge Gate, Merge, Issue/Project, permission, or protection operations.15. Verification commands
Run from an isolated checkout with no
node_modules,dist,.next, or untracked generated file. Keep the pinned Moss submodule unmodified; deinitialize it before the root Mini-Demo gate as established by #24.Manual production confirmation after build:
In a second terminal:
The response must match the frozen health object exactly and contain no RPC URL, host, secret, or credential.
Before handoff, run a pushed-branch fresh-clone proof with a new local pnpm store, repeat frozen install/Web build/tests/smokes/
pnpm check, and confirm the resulting worktree is clean apart from the reviewed 30-path commit diff.16. Acceptance and exit conditions
Implementation is acceptable only when all are true:
0.34.5;dist;next build, one-processnext start, loopback health smoke, browser leakage scan, and fullpnpm checkpass;tsconfig.json,apps/web/tsconfig.json,next-env.d.ts, package manifests, or lockfile during build;apps/web/.next/staticcontains no forbidden Moss/Clear402/server marker while server output contains the expected pinned metadata;quality-gatejob and succeeds;Stop without opening or updating a PR if:
22.23.1;A stop returns
SCOPE_CHANGES_REQUESTED; it does not authorize a workaround.17. Non-goals and trust boundaries
No implementation of:
moss-adapter,preflight-core, Quote/selection, Capability, simulation, Alignment, Decision orchestration, report generation, or presentation model;The Fake service and existing Fixtures are synthetic development tools. Production build/start, a health response, a strict API envelope, and green CI do not prove application correctness, protocol behavior, chain evidence, transaction safety, approval, authorization, execution, or permission to sign.
18. Risks and rollback
0.34.5is allowed to run a build script. Failure or extra build permission stops the task.FIXTURE; LIVE is explicitly unavailable and never downgraded.pnpm checkentry.apps/web, its workspace importer, scripts, Sharp allowlist, dependency graph, ignored build output, and the three current-state corrections together. No database, deployment, external service, secret, or user data exists to migrate or delete.19. Requested Maintainer Scope Gate
Please record one of:
SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZEDfor the exact 30 paths, dependency set, package policy, request/response/health fields, sizes, runId, Fake service, server-only boundary, tests, and verification contract above; orSCOPE_CHANGES_REQUESTEDwith the exact path, field, value, or ownership change required.Until that record exists:
pillowtalk-Qy commentedon Aug 5, 2026
SCOPE_CHANGES_REQUESTED
Reviewed Work Plan: #32 (comment)
Planning baseline:
main@93235e5c3ef531075c860beadc6ad2ce6b3dc8a0Reviewed Work Plan body SHA-256:
6e2a8e412f3d889ec58acfd719be474f06cafb8365872c43c02d7e304a31cab6The 30-path boundary, strict/fail-closed API contracts, server-only ownership, production build/start smoke, browser-bundle leakage gate, and prohibition on real Moss, Decision orchestration, Clear402 behavior, RPC, wallet, signing, and chain evidence are otherwise coherent with #22 and #32.
One supply-chain scope blocker prevents implementation authorization:
allowBuilds: { sharp: true }while claiming that build permission is limited to exactsharp@0.34.5. Under pnpm 11, an unversionedsharp: truematcher approves build scripts for the registry package name without fixing the version. It therefore does not implement the stated minimum, version-pinned permission boundary. pnpm supports version-qualified package matchers: https://pnpm.io/settings/build#allowbuildsRequired Work Plan correction:
'sharp@0.34.5': true; do not authorize the unversionedsharpmatcher.allowBuilds.sharpso the version-qualified matcher is the normative value.sharp: "0.34.5", the frozen lockfile resolution and integrity metadata, and the prohibition on any second build-script permission.22.23.1/ pnpm11.16.0install and Sharp import proof, and verify that no unreviewed build is reported or auto-added topnpm-workspace.yaml.No implementation is authorized from the current Work Plan. Submit a revised, closed Work Plan for a new Maintainer Scope Gate. Until
SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZEDis recorded, do not create the branch, worktree, commit, push, or PR.#32 remains Open, assigned to Qy, and Project In Progress for planning only. This is not QA, Review, READY_TO_MERGE, or merge authorization.
pillowtalk-Qy commentedon Aug 5, 2026
Revised Final Implementation Work Plan v2 - Version-Pinned Sharp Build Permission - Awaiting Maintainer Scope Confirmation
This complete revised plan supersedes, but does not edit or delete, the original Work Plan. It responds only to the Maintainer's SCOPE_CHANGES_REQUESTED; both earlier comments remain immutable audit records.
Unique revision delta
allowBuildskey is now the version-qualified matcher'sharp@0.34.5': true, replacing the unversionedsharp: trueproposal.pnpm-workspace.yaml.1. Planning control
main@93235e5c3ef531075c860beadc6ad2ce6b3dc8a0.PLANNING_ONLY / AWAITING_MAINTAINER_SCOPE_CONFIRMATION.codex/issue-32-web-api-baseline./Users/qy/Documents/moss-mini-demo-issue-32.SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZED.2. Goal and delivery boundary
Build a production-buildable and production-startable Next.js App Router skeleton on the accepted Node runtime, with:
POST /api/preflightrequest/response contracts;GET /api/healthresponse fields;This issue creates an application/API baseline, not an integrated demo. It does not implement Moss orchestration, Quote collection, Capability construction, simulation, Alignment, Decision Engine orchestration, report assembly, Monad/RPC access, Clear402 behavior, wallet behavior, signing, or transaction submission.
3. Frozen runtime and dependency set
Runtime and package manager:
The new
apps/web/package.jsondependency set is exact:{ "dependencies": { "@moss-mini-demo/report-schema": "workspace:*", "next": "16.2.12", "react": "19.2.3", "react-dom": "19.2.3", "server-only": "0.0.1", "sharp": "0.34.5", "zod": "4.4.3" }, "devDependencies": { "@types/node": "22.20.0", "@types/react": "19.2.18", "@types/react-dom": "19.2.4" } }No caret, tilde, tag, floating version, or additional dependency is authorized. The existing root TypeScript
7.0.2, Vitest4.1.10, and Biome2.5.5remain the only compiler/test/format toolchain.sharp@0.34.5is a reviewed direct runtime dependency because Next production image handling resolves it and its install script must not be silently blocked or broadly enabled.pnpm-workspace.yamlwill contain exactly:The version-qualified matcher
'sharp@0.34.5'is the normative build-script permission and the only key permitted underallowBuilds. The unversioned matchersharp: true,dangerouslyAllowAllBuilds, wildcard build permission, ignored-build bypass, and any second build-script permission are forbidden. pnpm must not automatically add an unreviewed placeholder, package matcher, or approval entry topnpm-workspace.yaml; any such mutation stops implementation. The lockfile must resolve Sharp exactly to0.34.5and retain package integrity metadata. A clean-store install must prove the reviewed Sharp script succeeds,pnpm ignored-buildsmust report no unreviewed build requiring a new permission, and a Node import must report Sharp0.34.5.4. Closed writable path list
Exactly these 30 repository paths are writable:
.gitignore- ignore Next build output only.package.json- add exact root web scripts/order; do not change existing dependency versions.pnpm-lock.yaml- generated frozen dependency graph and oneapps/webimporter only.pnpm-workspace.yaml- registerapps/*and contain exactly one build-script permission: the version-qualified matcher'sharp@0.34.5': true; no unversioned matcher, second permission, or pnpm-added placeholder.tsconfig.json- keep root strict checking but delegateapps/webto its own Next config.README.md- minimal stable current-state correction for the Web/API baseline.SECURITY.md- minimal stable boundary correction; no weakening of exclusions.docs/real-vs-mock.md- identify the Fake service and Fixtures as synthetic/non-evidence.apps/web/package.jsonapps/web/tsconfig.jsonapps/web/next-env.d.tsapps/web/next.config.tsapps/web/app/globals.cssapps/web/app/layout.tsxapps/web/app/page.tsxapps/web/app/api/health/route.tsapps/web/app/api/preflight/route.tsapps/web/src/contracts/health.tsapps/web/src/contracts/preflight.tsapps/web/src/server/moss-build-info.tsapps/web/src/server/run-id.tsapps/web/src/server/http-json.tsapps/web/src/server/preflight-service.tsapps/web/src/server/fake-preflight-service.tsapps/web/src/server/preflight-handler.tsapps/web/test/contracts.test.tsapps/web/test/fake-preflight-service.test.tsapps/web/test/routes.test.tsapps/web/test/browser-bundle-leak.smoke.mjsapps/web/test/production-start.smoke.mjsThere is no wildcard writable path. No generated asset, snapshot, public directory, fixture, application package, or 31st path may be added. In particular, this issue must not modify
.github/workflows/quality-gate.yml,.gitmodules,vendor/moss, anypackages/report-schemaorpackages/decision-enginefile, any ADR,docs/architecture.md,docs/security-boundary.md, or STOP presentation rules.5. Workspace, build, and script contract
.gitignoreadds.next/. No source path is ignored.The root
tsconfig.jsoncontinues strict no-emit validation for existing root/package code and excludesapps/**;apps/web/tsconfig.jsonowns DOM, JSX, Next plugin, JSON-module, incremental, and generated Next type settings. The committednext-env.d.tsuses only stable Next type references and does not import a missing.nextartifact, so zero-artifact typecheck remains valid. Roottypecheckmust explicitly invoke the Web package typecheck so exclusion cannot become a coverage gap.Root scripts retain the existing gate and use these exact semantics:
The Web package scripts are fixed as:
The public report package is built first so
pnpm --filter @moss-mini-demo/web buildand Web typecheck work in a clean checkout with no pre-existingdist. No TypeScript path alias to package-private source, committeddist, hidden lifecycle script, or postinstall hook is permitted. Test code cannot invoke a build; the existing roottestscript keeps its explicit build prerequisite visible.pnpm-lock.yamlchanges are limited to:apps/webimporter;The root importer and the two existing package importers must not gain unrelated dependencies. The lockfile is generated by pnpm
11.16.0, never manually edited. Build-script permission remains solely inpnpm-workspace.yamlas'sharp@0.34.5': true; it must not be duplicated, generalized, or represented by a generated placeholder.6. Strict POST /api/preflight request contract
The route is a Next Route Handler with
runtime = "nodejs", no Edge runtime, no Server Action, and no caching.Constants:
The request is a strict discriminated union. Every object uses Zod
strictObject; unknown keys are rejected.LIVE request:
{ "contractVersion": "0.1", "mode": "LIVE", "intent": "<value accepted by public IntentSchema>" }FIXTURE request:
{ "contractVersion": "0.1", "mode": "FIXTURE", "scenario": "manual-review-success" }The exact fixture scenario allowlist is:
Rules:
intentparsed only through public@moss-mini-demo/report-schemaIntentSchema; it forbidsscenario.scenario; it forbids caller-suppliedintentbecause each reviewed Fixture owns its synthetic intent.runId, RPC URL, chain endpoint, credential, arbitrary fixture path, protocol-module name, or extra property.LIVE | FIXTURE.Content-Lengthabove 65,536 bytes is rejected before reading. Missing or false-smallContent-Lengthdoes not bypass the streaming byte counter.request.json()first.7. runId ownership and format
The server route generates one run identifier immediately on entry, before media-type/body/schema validation, so every success and structured error can be correlated.
The format is:
apps/web/src/server/run-id.tsis the only generator and uses Nodecrypto.randomUUID(). The route creates it once, passes it read-only to the service, and returns the same value. A client cannot choose or overwrite it. A runId is transport correlation metadata, notreportId, provenance, evidence, authorization, or a replay/security token.8. Strict POST response and HTTP contract
All response objects are strict, versioned, schema-validated before serialization, measured as UTF-8 bytes, and emitted with:
Success is a strict mode-correlated union.
LIVE success:
{ "contractVersion": "0.1", "ok": true, "runId": "run_<uuid-v4>", "mode": "LIVE", "report": "<public PreflightReportSchema value>" }LIVE success permits only report provenance
LIVE_SOURCE | LOCAL_FORK.FIXTURE success:
{ "contractVersion": "0.1", "ok": true, "runId": "run_<uuid-v4>", "mode": "FIXTURE", "scenario": "manual-review-success", "report": "<public PreflightReportSchema value with provenance FIXTURE>" }The returned scenario must equal the requested allowlisted scenario. The Fake service maps the three scenario identifiers only to the three existing read-only Fixture files:
Every Fixture is parsed through the public
PreflightReportSchemabefore return. The Fake service does not copy, modify, repair, strengthen, or re-decide a Fixture.Structured error:
{ "contractVersion": "0.1", "ok": false, "runId": "run_<uuid-v4>", "error": { "code": "INVALID_REQUEST", "message": "Request does not match the preflight contract." } }The error code/status mapping is frozen:
INVALID_JSONINVALID_REQUESTREQUEST_TOO_LARGEUNSUPPORTED_MEDIA_TYPELIVE_UNAVAILABLERESPONSE_TOO_LARGEINTERNAL_ERRORError messages are fixed, non-sensitive strings of at most 256 characters. They do not include payloads, Zod issues, stack traces, filesystem paths, RPC data, environment values, or secrets. An HTTP error never includes a report or Decision and never masquerades as
STOP. An oversized success is not truncated and is not returned as partial evidence.9. Fake service public contract
apps/web/src/server/preflight-service.tsis the stable server-only interface owned by Web/API:The file imports
server-only. Future #25-#31 packages do not modify this interface; Issue #33 (M2-12) later replaces/injects the orchestration implementation under its own Scope Gate.The baseline
FakePreflightService:LIVE_UNAVAILABLEfor LIVE and never falls back to FIXTURE;apps/web/src/server/preflight-handler.tsowns HTTP parsing, limits, service invocation, response validation/size checking, and error mapping. The route file is a thin Node-runtime composition root. Tests may inject a contract-compatible service and runId generator into the handler factory; production uses the Fake service and real runId generator.10. GET /api/health contract
GET /api/healthreturns HTTP 200,application/json; charset=utf-8,cache-control: no-store, and exactly:{ "contractVersion": "0.1", "status": "ok", "app": { "name": "moss-mini-demo", "version": "0.0.0", "runtime": "nodejs", "nodeVersion": "22.23.1" }, "moss": { "sourceMode": "INTEGRATION_FORK", "upstreamCommit": "1ae6b6322d51fae9104f047efb94e601050b967f", "integrationCommit": "1ae6b6322d51fae9104f047efb94e601050b967f", "officialRelease": false, "packages": { "@themoss/core": "0.1.0", "@themoss/simulator": "0.1.0", "@themoss/protocol-kuru": "0.1.0", "@themoss/protocol-pancakeswap": "0.1.0" } }, "network": { "configured": false, "id": null }, "clear402": { "enabled": false } }The health route validates this value through the strict public
HealthResponseSchema. It returns no timestamp, hostname, IP, RPC URL/host, environment-variable name/value, credential, token, key, wallet, address, filesystem path, error detail, request data, or live network probe.configured: falseis status metadata, not evidence that a network check ran.11. Server-only and browser boundary
The accepted dependency direction remains:
All files under
apps/web/src/serverbegin withimport "server-only". Both Route Handlers explicitly use Node runtime. No Client Component imports a server file,vendor/moss, Moss package, futuremoss-adapter, futurepreflight-core, server environment, or Clear402 module.The minimal page is a static, non-interactive application placeholder only. It does not present Fixture output as live evidence and does not claim that a runnable integrated demo exists.
After production build,
browser-bundle-leak.smoke.mjsrecursively scansapps/web/.next/static. It fails on these case-insensitive markers:The smoke also requires at least one static JS artifact and separately proves the server output contains the exact integration commit and
@themoss/coremarker. This makes the negative browser scan meaningful rather than passing because the server metadata was omitted.No
clear402-profiledependency or import is added. The health response's server-sideclear402.enabled=falseis status only and cannot alter Core behavior or evidence.12. Tests and required coverage
apps/web/test/contracts.test.tscovers:IntentSchemavalidation;apps/web/test/fake-preflight-service.test.tscovers:PreflightReportSchemaacceptance;provenance: FIXTUREand exact Fixture Decision;LIVE_UNAVAILABLEwith no Fixture fallback;apps/web/test/routes.test.tscovers:apps/web/test/browser-bundle-leak.smoke.mjsruns only after production build and applies the server/static assertions above.apps/web/test/production-start.smoke.mjs:.nextbuild;pnpm startpath withNEXT_TELEMETRY_DISABLED=1;GET /api/health;The smoke binds only
127.0.0.1; it performs no external HTTP, RPC, protocol, wallet, or chain call.13. Documentation corrections
The three authorized current-state documents receive minimal, stable facts:
provenance: FIXTURE;LIVE_UNAVAILABLEin this baseline and never silently fall back;MANUAL_REVIEWandSTOPmeanings are unchanged;docs/architecture.md,docs/security-boundary.md, ADRs, M1 evidence, and #23 Scope Cut documentation are not changed.14. Implementation sequence after authorization
origin/main. If it differs from93235e5c3ef531075c860beadc6ad2ce6b3dc8a0, stop, scan the new main, and request a refreshed Scope Gate before branching.allowBuildsentry to the exact matcher'sharp@0.34.5': true, then generate the lockfile only with Node22.23.1and pnpm11.16.0; audit the importer, exact versions, integrities, peer links, unexpected package scripts, andpnpm ignored-builds. Confirm pnpm did not add an unreviewed placeholder or second permission topnpm-workspace.yaml.feat: add Web API baseline and strict contractswithCloses #32only.quality-gatesuccess, update the Implementation Report, add a Pre-PR QA handoff, freeze the head, and stop. Do not execute Review, Ready, Merge Gate, Merge, Issue/Project, permission, or protection operations.15. Verification commands
Run from an isolated checkout with no
node_modules,dist,.next, or untracked generated file. Keep the pinned Moss submodule unmodified; deinitialize it before the root Mini-Demo gate as established by #24.Manual production confirmation after build:
In a second terminal:
The response must match the frozen health object exactly and contain no RPC URL, host, secret, or credential.
Before handoff, run a pushed-branch fresh-clone proof with a new local pnpm store, repeat frozen install/Web build/tests/smokes/
pnpm check, and confirm the resulting worktree is clean apart from the reviewed 30-path commit diff. In both isolated installs,pnpm config get allowBuilds --jsonmust resolve semantically to exactly{"sharp@0.34.5":true},pnpm ignored-buildsmust identify no unreviewed build requiring another permission, and the pre/post-install workspace-policy hashes must match so pnpm cannot silently add a placeholder.16. Acceptance and exit conditions
Implementation is acceptable only when all are true:
'sharp@0.34.5': true;0.34.5;dist;next build, one-processnext start, loopback health smoke, browser leakage scan, and fullpnpm checkpass;pnpm-workspace.yaml,tsconfig.json,apps/web/tsconfig.json,next-env.d.ts, package manifests, or lockfile during install/build;apps/web/.next/staticcontains no forbidden Moss/Clear402/server marker while server output contains the expected pinned metadata;quality-gatejob and succeeds;Stop without opening or updating a PR if:
22.23.1;A stop returns
SCOPE_CHANGES_REQUESTED; it does not authorize a workaround.17. Non-goals and trust boundaries
No implementation of:
moss-adapter,preflight-core, Quote/selection, Capability, simulation, Alignment, Decision orchestration, report generation, or presentation model;The Fake service and existing Fixtures are synthetic development tools. Production build/start, a health response, a strict API envelope, and green CI do not prove application correctness, protocol behavior, chain evidence, transaction safety, approval, authorization, execution, or permission to sign.
18. Risks and rollback
'sharp@0.34.5': truemay authorize a build script. An unversioned matcher, install/import failure, ignored unreviewed build, or extra permission stops the task.FIXTURE; LIVE is explicitly unavailable and never downgraded.pnpm checkentry.pnpm-workspace.yamlhash, structured config output, ignored-build report, and exact diff make any mutation a hard stop.apps/web, its workspace importer, scripts, the exact'sharp@0.34.5': truepermission, dependency graph, ignored build output, and the three current-state corrections together. No database, deployment, external service, secret, or user data exists to migrate or delete.19. Requested Maintainer Scope Gate
Please record one of:
SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZEDfor the exact 30 paths, dependency set, sole version-qualified'sharp@0.34.5': truebuild permission, prohibition on any second permission or pnpm-added placeholder, request/response/health fields, sizes, runId, Fake service, server-only boundary, tests, and verification contract above; orSCOPE_CHANGES_REQUESTEDwith the exact path, field, value, or ownership change required.Until that record exists:
pillowtalk-Qy commentedon Aug 5, 2026
SCOPE_CONFIRMED / IMPLEMENTATION_AUTHORIZED
Authorized Work Plan: #32 (comment)
Implementation baseline:
main@93235e5c3ef531075c860beadc6ad2ce6b3dc8a0Authorized Work Plan body SHA-256:
9b950740ed7008f89c4801a02c80624892ea38c7ae34e4aa58283c1d97b14561Maintainer Scope Gate result: PASS.
The revised Work Plan is authorized with these frozen boundaries:
allowBuildsentry:'sharp@0.34.5': true; the unversioned Sharp matcher, any second matcher, any pnpm-added placeholder, and any broader build-script permission are forbidden;The original Work Plan remains an unchanged audit record. The revised plan is a separate comment and the only authorized implementation source.
Builder Qy may now re-fetch and confirm the exact baseline, then create only the planned
codex/issue-32-web-api-baselinebranch and isolated worktree, implement the authorized scope, and open one Draft PR withCloses #32only. Ifmainchanges before branching, or implementation needs another path, dependency, build permission, public contract, workflow, or scope, stop and request a new Maintainer Scope Gate.This record authorizes implementation only. It is not Pre-PR QA, an independent review, READY_TO_MERGE, Merge Gate, or merge authorization. The implementation PR must remain Draft until its exact-head QA handoff and subsequent Maintainer review.
#32 remains Open, assigned to
pillowtalk-Qy, and Project In Progress. No downstream Issue is released by this authorization.feat: add Web API baseline and strict contracts (#71)
pillowtalk-Qy commentedon Aug 5, 2026
POST_MERGE_AUDIT
PR: #71
39ded5f45322d1fe79811c8908b067ad94f71d54main@93235e5c3ef531075c860beadc6ad2ce6b3dc8a01e42babfa457ad20ac1efcecca227aceb4995c2b2026-08-05T10:57:54Z93235e5c3ef531075c860beadc6ad2ce6b3dc8a0(single parent)The merged-main check ran against exact head
1e42babfa457ad20ac1efcecca227aceb4995c2b. Issue #32 is Closed / Completed and its Project status is Done.The merge used head-matched squash merge. No auto-merge or admin bypass was used. No protection, permission, Tag, or Release setting was changed.