Skip to content

Commit e981a0c

Browse files
committed
개선: package engine 기본 진입 확정
Machine profile initializer가 설치본의 owned CPython을 기본 선택하고 명시 경로는 override로 보존한다. 도움말과 사용 문서, 설치 tarball 및 제품 계약 게이트를 짧아진 진입 명령에 맞췄다. 검증: npm test, npm run test:contracts, npm run test:package, npm run test:mcp-product GREEN.
1 parent 17d9652 commit e981a0c

14 files changed

Lines changed: 99 additions & 64 deletions

File tree

mainPlan/9-agentComputerStandardReadiness/README.md

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Initiative 9: agent computer와 웹 표준 후보 준비도
22

3-
상태: **진행 중, M0 완료, M1 대기**
3+
상태: **진행 중, M0 완료, M1 첫 하위 계약 완료**
44

55
이 문서는 agent가 pyproc에 들어와 보고, 행동하고, 계산하고, 세션을 넘겨 계속 일하는 전 과정을
66
제품 기준으로 끌어올리는 실행 원장이다. 기존 능력 점수와 증거의 정본은
@@ -14,7 +14,7 @@
1414

1515
| 질문 | 현재 판정 | 실사용 증거 | 완성까지 남은 것 |
1616
|---|---|---|---|
17-
| agent 진입점 | 강함, 완성 아님 | exact install, `pythonOnly` init, effect-free doctor, CPython 실행이 공개 명령으로 완결 | 성공한 startup timeout timer가 Node를 기본 30초까지 붙잡는 수명주기 결함 제거 |
17+
| agent 진입점 | 강함, 완성 아님 | exact install`pythonOnly` init, effect-free doctor, CPython 실행이 공개 명령으로 완결되고 현재 main은 package engine을 자동 선택 | 첫 문서 교체 자동 수렴과 client별 다음 명령 의미 통일 |
1818
| 눈과 팔 | 강함, 완성 아님 | APX Situation이 링크를 식별하고 proof-carrying click 뒤 `Smallest start` 출현을 confirmed로 봉인 | 첫 문서 교체 복구 여정, 장기 반복 수명주기, 실제 GPU visual oracle 확대 |
1919
| 비-agent 컴퓨팅 몸체 | 훌륭한 브라우저 컴퓨터, 로컬 OS 완전 대체는 아님 | owned CPython, worker process, OPFS disk, checkpoint, Machine image, Python과 x86 guest gate | 임의 native wheel, shared-memory thread, wasm 도구층, Node guest, quota 축출 계약 |
2020
| 단독 자립성 | Python 기본 Machine은 높음, 전체 WebComputer는 미완성 | source-built CPython과 stdlib가 npm에 포함되고 기본 부팅의 제3자 요청은 0 | x86 emulator와 firmware의 독립 재현, GPU 실기 CI, 브라우저 범위 확대 |
@@ -69,12 +69,19 @@ implementation experience는 독립적이고 상호운용 가능한 구현, 저
6969

7070
### M1. Machine Entrance 첫 결과 수렴
7171

72-
판정: **다음 작업**
72+
판정: **진행 중**
7373

74-
- exact version 설치 뒤 engine 경로를 사람이 조립하지 않아도 되는 공개 recipe를 확정한다.
74+
- 완료: exact version 설치 뒤 engine 경로를 사람이 조립하지 않아도 package-owned CPython을 선택한다.
75+
명시한 `--engine-root`만 override로 사용하며 결과와 생성 README에 선택 출처와 절대 경로를 남긴다.
7576
- COI bootstrap의 첫 문서 교체를 관찰, 재발급, bounded retry 계약으로 한 번에 수렴시킨다.
7677
- doctor의 다음 명령이 shell, JavaScript, Python, MCP에서 같은 의미를 가진다.
7778

79+
첫 하위 계약 증거:
80+
81+
- `pyproc-mcp init --recipe pythonOnly`가 설치 tarball 내부 owned engine으로 manifest를 만든다.
82+
- 순수 parser는 package 경로를 추측하지 않고 initializer만 설치 경계를 해석한다.
83+
- contract 36 suites, package gate, 전체 12개 게이트, 설치 MCP 제품 20개가 GREEN이다.
84+
7885
### M2. Eyes와 Arms 장기 수명주기
7986

8087
- 반복 Situation, screenshot, proof-carrying action, artifact cleanup에서 handle과 process 잔류 0을 증명한다.

scripts/machineEntrance/profileInitializer.js

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import { compileMachineProfile } from "./machineProfile.js";
77

88
export const MACHINE_PROFILE_DIRECTORY = ".pyproc";
99
export const MACHINE_PROFILE_FILES = Object.freeze(["manifest.json", "client.json", "README.md"]);
10+
export const MACHINE_PROFILE_ENGINE_RELATIVE_PATH = Object.freeze([
11+
"src", "runtime", "engines", "wasi", "owned", "core",
12+
]);
1013

1114
async function exists(path) {
1215
try { await access(path, constants.F_OK); return true; } catch (error) { return false; }
@@ -47,10 +50,11 @@ function clientSource(manifestPath) {
4750
}, null, 2)}\n`;
4851
}
4952

50-
function readmeSource({ recipe, manifestPath, output }) {
53+
function readmeSource({ recipe, manifestPath, output, engine }) {
5154
return `# pyproc Machine profile
5255
5356
Recipe: \`${recipe}\`
57+
Engine: \`${engine.root}\` (${engine.source === "packageDefault" ? "installed package default" : "explicit override"})
5458
5559
This directory contains a fully expanded authority manifest. The recipe name is descriptive and does not
5660
grant authority at runtime. The manifest remains subject to the strict product validator.
@@ -82,14 +86,15 @@ async function packageVersion(packageRoot) {
8286
return version;
8387
}
8488

85-
function sourcesFor({ profile, output }) {
89+
function sourcesFor({ profile, output, engineSource }) {
8690
const manifestPath = join(output, "manifest.json");
87-
const manifest = `${JSON.stringify(compileMachineProfile(profile), null, 2)}\n`;
88-
return new Map([
89-
[manifestPath, manifest],
91+
const compiled = compileMachineProfile(profile);
92+
const engine = Object.freeze({ source: engineSource, root: compiled.engine.root });
93+
return Object.freeze({ engine, files: new Map([
94+
[manifestPath, `${JSON.stringify(compiled, null, 2)}\n`],
9095
[join(output, "client.json"), clientSource(manifestPath)],
91-
[join(output, "README.md"), readmeSource({ recipe: profile.recipe, manifestPath, output })],
92-
]);
96+
[join(output, "README.md"), readmeSource({ recipe: profile.recipe, manifestPath, output, engine })],
97+
]) });
9398
}
9499

95100
async function writeAtomically(files, { overwrite }) {
@@ -144,7 +149,13 @@ export async function initializeMachineProfile({
144149
throw new TypeError("Machine profile overwrite and dryRun must be boolean");
145150
}
146151
const paths = await normalizedOutput(projectRoot, outputDir);
147-
const files = sourcesFor({ profile, output: paths.output });
152+
const usesPackageEngine = profile?.engineRoot === undefined;
153+
const resolvedProfile = usesPackageEngine && profile && typeof profile === "object" && !Array.isArray(profile)
154+
? { ...profile, engineRoot: join(resolve(packageRoot), ...MACHINE_PROFILE_ENGINE_RELATIVE_PATH) }
155+
: profile;
156+
const generated = sourcesFor({ profile: resolvedProfile, output: paths.output,
157+
engineSource: usesPackageEngine ? "packageDefault" : "explicit" });
158+
const files = generated.files;
148159
const present = [];
149160
for (const path of files.keys()) if (await exists(path)) present.push(path);
150161
if (present.length && !overwrite) {
@@ -163,8 +174,9 @@ export async function initializeMachineProfile({
163174
}
164175
return Object.freeze({
165176
ok: true,
166-
recipe: profile.recipe,
177+
recipe: resolvedProfile.recipe,
167178
package: Object.freeze({ name: "pyproc", version }),
179+
engine: generated.engine,
168180
projectRoot: paths.root,
169181
output: paths.output,
170182
manifestPath: join(paths.output, "manifest.json"),

scripts/pyprocMcp.mjs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { parseMachineProfileInitArguments } from "./machineEntrance/entranceCli.
1010
import { initializeMachineProfile } from "./machineEntrance/profileInitializer.js";
1111

1212
const HELP = `Usage:
13-
pyproc-mcp init --recipe <name> --engine-root <directory> [options]
13+
pyproc-mcp init --recipe <name> [options]
1414
pyproc-mcp --config <file> [--check]
1515
1616
Options:
@@ -31,12 +31,13 @@ existing generated profile explicitly.
3131
`;
3232

3333
const INIT_HELP = `Usage:
34-
pyproc-mcp init --recipe <name> --engine-root <directory> [options]
34+
pyproc-mcp init --recipe <name> [options]
3535
3636
Profile:
3737
--project-root <directory> Existing project root, defaults to the current directory
3838
--out <directory> Project-relative output, defaults to .pyproc
3939
--recipe <name> pythonOnly, observeLocal, authorizedBrowser, replayPinned, or transactionalApp
40+
--engine-root <directory> Override the installed package's owned CPython engine
4041
--timeout-ms <n> Product operation timeout
4142
--dry-run Compile and report paths without writing
4243
--overwrite Explicitly replace an existing generated profile

skills/automate-browser-with-pyproc/references/browser-automation.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ Compile the common authorized profile without hand-editing JSON:
4242
```sh
4343
npx pyproc-mcp init \
4444
--recipe authorizedBrowser \
45-
--engine-root /absolute/path/to/cpython-wasi \
4645
--origin https://example.test \
4746
--action snapshot --action screenshot --action waitFor \
4847
--action hydrateLazy --action navigate --action fill --action click \

skills/catalog.json

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"format": "pyproc-skill-catalog",
33
"version": 1,
4-
"generatedFromDigest": "sha256:73d00e9b3bbfc2ac4ef12dbaef447ff58f26006c5b4f221a69244fca14271a05",
5-
"catalogDigest": "sha256:e8ea587cf3d39528009491509b46e4f6b48e85ac92784a34bbcfd48093b5b790",
4+
"generatedFromDigest": "sha256:9c06919dd70f238862b63ebad7cbee841a1a729b4ef6e8fad7bb8f7c89c7b752",
5+
"catalogDigest": "sha256:891dd216f8d13753cefd65d64000e0974ece48da29315938b2dc3874be2d3cc6",
66
"skills": [
77
{
88
"name": "automate-browser-with-pyproc",
@@ -259,8 +259,8 @@
259259
},
260260
{
261261
"path": "skills/automate-browser-with-pyproc/references/browser-automation.md",
262-
"bytes": 24898,
263-
"sha256": "sha256:e4d1521aa7e437d9518b8a70f688d5df74dbd27a72f5acd65d9a249240ff1e84"
262+
"bytes": 24849,
263+
"sha256": "sha256:2e227a6abdab284468f73d640935f2de3ecc3bbb260eb8c657648a480f646812"
264264
},
265265
{
266266
"path": "skills/automate-browser-with-pyproc/references/frame-space.md",
@@ -279,23 +279,23 @@
279279
},
280280
{
281281
"path": "skills/commit-pyproc-effects/references/rehearse-commit.md",
282-
"bytes": 23161,
283-
"sha256": "sha256:1db925b8a4869a5df11da96e5c13fd4a48b8b080cb7a9e8294d4da222130b63f"
282+
"bytes": 23112,
283+
"sha256": "sha256:32a701b9a4051380d294ba770322055094f07b6f3fbc4a6dce8c0ef22fdb0fc5"
284284
},
285285
{
286286
"path": "skills/control-pyproc/references/control-protocol.md",
287-
"bytes": 17721,
288-
"sha256": "sha256:a0cfd3bf7a32384ead125c19e0c5d53ebc52bb11fa95a476bc76425ccf77c497"
287+
"bytes": 17676,
288+
"sha256": "sha256:0eef53dddc2a170007da9deecfa23da5ab888d236e0afd007f45d1fe3d883c13"
289289
},
290290
{
291291
"path": "skills/control-pyproc/references/javascript-control.md",
292-
"bytes": 13418,
293-
"sha256": "sha256:a8039207d55f0bd8188702566733adf58f430ce18ea1c4612d1b7c172f3918ea"
292+
"bytes": 13324,
293+
"sha256": "sha256:9aa6c56619822bb1d976002a7f2ebe0de5a219e43dbb6d4adadd645510df98d0"
294294
},
295295
{
296296
"path": "skills/control-pyproc/references/python-sdk.md",
297-
"bytes": 14967,
298-
"sha256": "sha256:8bf700408f7cd8c580b49c41a72fc6c458c3b68e30af26b176311c291442def3"
297+
"bytes": 14922,
298+
"sha256": "sha256:68301dc1ad32c591af3490d3dfd0c49a7c68b1ae5f803133ea0bc28ec5482d75"
299299
},
300300
{
301301
"path": "skills/develop-pyproc/references/module-boundaries.md",
@@ -374,8 +374,8 @@
374374
},
375375
{
376376
"path": "skills/transact-pyproc-app-state/references/app-space.md",
377-
"bytes": 17480,
378-
"sha256": "sha256:20456153aa33fe25ad5707b797dbe349b5ce120d90a7d212a2f935545ab24ae9"
377+
"bytes": 17431,
378+
"sha256": "sha256:6f47730d99e511b38845f0aec4d25a0fdf3455621c041e00e68ab944bf5ccf29"
379379
},
380380
{
381381
"path": "skills/understand-pyproc/references/capability-matrix.md",
@@ -399,8 +399,8 @@
399399
},
400400
{
401401
"path": "skills/use-pyproc-machine/references/machine-entrance.md",
402-
"bytes": 8896,
403-
"sha256": "sha256:f86431134980d6e9b8fcde47fe87057be63865b5213b6b9d39964c47e10ec201"
402+
"bytes": 8554,
403+
"sha256": "sha256:efeb28d4bf4564481cdee5f2f7197f44c7704b0cd1c7bf5100ac3a4290cd701c"
404404
},
405405
{
406406
"path": "skills/use-pyproc-machine/references/machine-fleet.md",

skills/commit-pyproc-effects/references/rehearse-commit.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ and put only its public key in the product profile.
5353
```sh
5454
npx pyproc-mcp init \
5555
--recipe authorizedBrowser \
56-
--engine-root /absolute/path/to/cpython-wasi \
5756
--origin https://work.example.test \
5857
--action snapshot --action click \
5958
--max-risk externalEffect \

skills/control-pyproc/references/control-protocol.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ the official Python client is documented in the [Python SDK guide](./python-sdk.
2626
Compile a profile and run the complete effect-free doctor before starting the protocol:
2727

2828
```sh
29-
npx pyproc-mcp init --recipe pythonOnly --engine-root /absolute/path/to/cpython-wasi
29+
npx pyproc-mcp init --recipe pythonOnly
3030
npx pyproc-control doctor --config ./.pyproc/manifest.json
3131
npx pyproc-control run --config ./.pyproc/manifest.json --code "40 + 2"
3232
```

skills/control-pyproc/references/javascript-control.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Create the version 1 policy manifest with [Machine Entrance](../../use-pyproc-ma
3535
starting a live product:
3636

3737
```sh
38-
npx pyproc-mcp init --recipe pythonOnly --engine-root /absolute/path/to/cpython-wasi
38+
npx pyproc-mcp init --recipe pythonOnly
3939
npx pyproc-control doctor --config ./.pyproc/manifest.json
4040
```
4141

@@ -81,7 +81,6 @@ Enable it when creating the profile, then publish the current Machine as an immu
8181
```sh
8282
npx pyproc-mcp init \
8383
--recipe pythonOnly \
84-
--engine-root /absolute/path/to/cpython-wasi \
8584
--execution-memory-root /absolute/private/pyproc-memory
8685
```
8786

skills/control-pyproc/references/python-sdk.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Create the version 1 manifest with [Machine Entrance](../../use-pyproc-machine/r
4646
`"browser": { "enabled": false }`. Run the complete doctor before use:
4747

4848
```sh
49-
npx pyproc-mcp init --recipe pythonOnly --engine-root /absolute/path/to/cpython-wasi
49+
npx pyproc-mcp init --recipe pythonOnly
5050
npx pyproc-control doctor --config ./.pyproc/manifest.json
5151
```
5252

skills/transact-pyproc-app-state/references/app-space.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ compile the `transactionalApp` recipe:
3838
```sh
3939
npx pyproc-mcp init \
4040
--recipe transactionalApp \
41-
--engine-root /absolute/path/to/cpython-wasi \
4241
--origin https://workspace.example.test \
4342
--action snapshot --action click \
4443
--purpose "branch the cooperative workspace" \

0 commit comments

Comments
 (0)