@jsonstudio/appsdk-linux-x64-gnu 0.0.0-stage → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,157 @@
1
+ # AppSDK State Paths and Components
2
+
3
+ ## Global truth
4
+
5
+ Host-wide AppSDK governance and Collab truth are separate:
6
+
7
+ ```text
8
+ ~/.appsdk
9
+ projects.jsonl
10
+ runtimes.jsonl
11
+ communication.jsonl
12
+ config.toml
13
+
14
+ ~/.collab
15
+ server.sock
16
+ daemon.lock
17
+ server.pid
18
+ events.jsonl
19
+ log.txt
20
+ routes.jsonl
21
+ ```
22
+
23
+ Usage:
24
+
25
+ - `~/.appsdk` is AppSDK's global persistent truth. It is not a project
26
+ directory. Do not hand-edit or delete its `.jsonl` files; AppSDK updates them
27
+ through its commands and reset/migration lifecycle.
28
+ - `~/.collab` is Collab's host-level daemon truth. It is owned by Collab, not
29
+ AppSDK. Do not hand-edit or delete its files; see the Collab skill's
30
+ `state-paths.md`.
31
+ - Deleting a project root does not authorize deleting global truth entries.
32
+ Global entries are retired through the owning lifecycle.
33
+
34
+ ## Project-local AppSDK state
35
+
36
+ For a governed project root:
37
+
38
+ ```text
39
+ <project>/.appsdk/
40
+ project.json
41
+ goal.json
42
+ sdk.lock
43
+ contracts/
44
+ records/
45
+ maps/
46
+ guidance/
47
+ skills/
48
+
49
+ <project>/.appsdk-control/
50
+ run state
51
+ temporary guidance/harness output
52
+ local runtime state
53
+
54
+ <project>/.agent-collab/
55
+ project registration/reducer input
56
+ ```
57
+
58
+ Usage:
59
+
60
+ - `.appsdk/project.json` is the project governance contract. After
61
+ `appsdk init`, it contains placeholder `project_id: "change-me"`, `goal.json`
62
+ contains `goal-change-me`, and the module scaffold contains `app-core`.
63
+ Replace those with the real project contract before `appsdk verify`.
64
+ - `.appsdk-control/` is local runtime state and is not committed truth. It is
65
+ removed or reset through AppSDK reset/init, not by hand-deleting arbitrary
66
+ files.
67
+ - `.agent-collab/` is Collab-owned project registration/reducer input. It is
68
+ not the peer, route, mailbox, task, or liveness truth. AppSDK reset must not
69
+ delete it; Collab migration/retirement owns it.
70
+ - A Git worktree contains tracked `.appsdk/` files from its main checkout, but
71
+ does not inherit ignored `.agent-collab/` or `.appsdk-control/` state. The
72
+ registered peer identity is inherited from the global Collab state by the
73
+ current Codex sessionID/App Server thread; do not create a second project
74
+ registration from a worktree.
75
+
76
+ ## Lifecycle commands and meaning
77
+
78
+ ```text
79
+ appsdk prepare -> create/confirm scope and boundaries
80
+ appsdk init . -> scaffold/refresh governance and register project
81
+ appsdk guide compile -> compile declared guidance after binding the contract
82
+ appsdk verify -> verify the current contract/baseline
83
+ appsdk reset-governance <project> --discard-legacy
84
+ -> AppSDK control-plane reset
85
+ appsdk init --fresh --discard-legacy
86
+ -> preferred single transaction for old AppSDK control plane
87
+ collab down
88
+ collab reset --project --discard-legacy --approval "<user text>"
89
+ collab up
90
+ collab context
91
+ -> Collab-owned project control-plane reset
92
+ ```
93
+
94
+ For old `.appsdk/` state, do not delete it manually. Use the authorized reset
95
+ route after the Collab side is migrated or retired. `appsdk init --fresh
96
+ --discard-legacy` removes the AppSDK-owned old control plane and rebuilds the
97
+ current baseline; it does not delete `.agent-collab/` or global truth.
98
+
99
+ When the user explicitly asks to start fresh instead of migrating legacy
100
+ state, keep the owners separate:
101
+
102
+ 1. Use `collab migrate` when the project journal is replayable; otherwise use
103
+ the explicitly authorized `collab reset --project --discard-legacy` sequence above
104
+ for Collab-owned state. Do not manually remove `.agent-collab/`.
105
+ 2. From a clean non-`main` owner worktree, use `appsdk init --fresh
106
+ --discard-legacy` for `.appsdk/` and `.appsdk-control/`. Do not manually
107
+ remove either AppSDK-owned root.
108
+ 3. Initialize and bind the current project contract, then run `appsdk guide
109
+ compile` and `appsdk verify`. A reset proves only reset; it does not prove
110
+ delivery, review, install, restart, or communication.
111
+
112
+ ## Registration verification
113
+
114
+ ### Where registration and identity queries run
115
+
116
+ `collab context` is the single agent identity bootstrap. AppSDK project
117
+ initialization remains its own owner and may invoke the same daemon context
118
+ internally; the agent must not rerun AppSDK initialization or run another
119
+ identity command to repair pending Collab. Run `collab context` once from the
120
+ project or worktree. Global Collab state resolves the current Codex
121
+ sessionID/App Server thread to the canonical route and reports the inherited
122
+ identity, liveness, tasks, inbox, `next_actions`, and master/authority state.
123
+ `registered: true` ends bootstrap. If the snapshot returns `required_fields`,
124
+ supply only those real facts once:
125
+
126
+ ```sh
127
+ collab context --provide '<JSON>'
128
+ ```
129
+
130
+ The supplement may contain only requested `session_id`, `thread_id`,
131
+ `endpoint`, or `namespace` facts; it never supplies a worker, approval, token,
132
+ route, or binding. The supplement invocation returns the resulting snapshot.
133
+ `collab context` is the registration truth for `authority`, `identity`, `inbox`, `liveness`,
134
+ `master`, `next_actions`, `role_brief`, `tasks`, and
135
+ `truth`. Registration returns the brief effective at registration; `collab
136
+ context` projects the current brief, and promotion or delegation returns the
137
+ replacement brief. Read master/authority state from the same snapshot. A live
138
+ master exists iff the returned `master` is an object with
139
+ `endpoint_live=true`. `master: null` means no live master is recorded; a
140
+ `master` object with `endpoint_live=false` is a recorded-but-dead identity and
141
+ is not a live master. Do not run a separate master, route, or worker query for
142
+ bootstrap. Do not inspect journal, mailbox, `routes.jsonl`, or `~/.collab`
143
+ paths to prove registration. Missing or failed identity prevents claiming
144
+ registration.
145
+
146
+ If `collab context` explicitly reports daemon DOWN, a runtime error,
147
+ `PROJECT_SCOPE_UNKNOWN`, or `token mismatch`, preserve the exact error and stop
148
+ identity repair. Do not infer worktree scope from the error code alone, do not
149
+ silently switch to a guessed parent or another project, and do not copy or edit
150
+ identity/token state. If the snapshot shows a live master, report the exact
151
+ context error to that master. If no live master exists, report it to the
152
+ explicitly authorized migration/reset owner or the user. Do not re-register
153
+ the worktree, start a daemon, reset the project, or promote a peer. Daemon
154
+ lifecycle maintenance is human-authorized.
155
+
156
+ See [`init-prompts.md`](init-prompts.md) for copy/paste master and peer
157
+ initialization prompts.
@@ -0,0 +1,134 @@
1
+ # Persistent subworkers and shared policy
2
+
3
+ This reference describes the persistent **subworker** policy. The `[subagent]`
4
+ tables and `appsdk-subagent` MCP name are compatibility protocol tokens. They
5
+ do not mean that Codex Desktop should use a native task/thread spawn command.
6
+
7
+ Only `~/.appsdk/config.toml` owns startup/notification/timer policy. Run
8
+ `appsdk config` from the project cwd to validate and inspect effective values.
9
+ Global defaults work when the file is absent; project overrides stay in
10
+ `[[projects]]` tables in that same file. Git worktrees inherit their main
11
+ project's policy. Never copy Codex credentials or rewrite its profiles.
12
+
13
+ ```toml
14
+ [notifications]
15
+ enabled = true
16
+ mode = "batch" # immediate or batch
17
+ batch_window_seconds = 60
18
+ transport = "appserver"
19
+ submit_enter = true
20
+ [notifications.events.deadline]
21
+ mode = "immediate"
22
+ [timers]
23
+ enabled = true
24
+ tick_interval_ms = 1000
25
+ [keepalive]
26
+ enabled = true
27
+ interval_seconds = 900 # minimum 15 minutes
28
+ max_unacked = 3 # legacy delivery throttle; recv consumes notifications
29
+ [subagent]
30
+ profile_priority = ["gcm", "oauth"]
31
+ persistent = true
32
+ close_on_task_complete = false
33
+ [subagent.profiles.gcm]
34
+ codex_profile = "gcm"
35
+ [subagent.profiles.oauth]
36
+ codex_profile = "oauth"
37
+ model = "gpt-5.6-luna"
38
+ [subagent.health]
39
+ timeout_seconds = 45
40
+ attempts_per_profile = 1
41
+ expected_response = "OK"
42
+ [subagent.startup]
43
+ ready_timeout_seconds = 90
44
+ # Optional:
45
+ # [[projects]]
46
+ # root = "/absolute/project/root"
47
+ # [projects.notifications]
48
+ # mode = "immediate"
49
+ ```
50
+
51
+ Event keys: `direct_message`, `resource_released`, `deadline`;
52
+ each accepts `mode = "inherit" | "immediate" | "batch"`. A fixed batch window
53
+ does not slide when new messages arrive. Disabled timers suppress deadline
54
+ notification generation, not task timeout safety checks. New subworkers read
55
+ config at creation; existing daemons read policy at startup. Use controlled
56
+ daemon restart after a policy change. Existing tasks/mailboxes remain intact.
57
+
58
+ From a registered Codex App Server parent:
59
+
60
+ ```text
61
+ appsdk subworker start --id <unique-request-id>
62
+ appsdk subworker list
63
+ appsdk subworker status <id>
64
+ appsdk subworker snapshot <id> --lines 40
65
+ appsdk subworker send <id> --subject <topic> "<task>"
66
+ appsdk subworker close <id>
67
+ ```
68
+
69
+ `start` probes each configured profile once, bounded by timeout, then launches
70
+ one Codex session. Reusing an ID returns the existing record, never restarts
71
+ it. `starting` is not `idle`: Codex may require trust/auth/approval interaction.
72
+ Use status; do not inject automatic confirmation or keep re-sending tasks.
73
+ All profiles failing returns a failed record with reasons and no launch.
74
+
75
+ An already trusted cwd and healthy authenticated profile should start without
76
+ new trust/auth interaction. Repeated prompts on that path are a startup bug,
77
+ not an instruction to reinitialize credentials or accept prompts automatically.
78
+
79
+ ## Finite task keepalive and observation
80
+
81
+ `send` creates the canonical `task-<message-id>` task in the Collab task list.
82
+ Child `working` claims it; bind code work with `collab_task_relocate`, not a
83
+ duplicate task registration. Complete the real task lifecycle; `ready` changes
84
+ session availability only and never marks unfinished tasks complete.
85
+
86
+ Unfinished actionable tasks are grouped by worker. Explicit idle for 15 minutes
87
+ allows one activation. Read the notification with `collab recv`; reading consumes
88
+ it atomically, so a normal follow-up ACK is not required. Messages sent by the
89
+ worker and positive working observations count as activity. Unknown remains
90
+ unknown; absent/unknown/working receive no activation. Blocked/waiting tasks
91
+ follow their declared wait, not this continuation path.
92
+
93
+ Three consecutive unconfirmed attempts exhaust the durable budget. After the
94
+ third response window, status marks `suspected_offline`; it does not claim the
95
+ process is dead. Failed/uncertain sends count, restart does not reset the budget,
96
+ and no process is respawned. Only an explicit parent/operator request may use
97
+ `appsdk subworker rearm <id>`; never rearm automatically to bypass exhaustion.
98
+
99
+ `status` returns observed state, task list, parent mailbox, keepalive counters
100
+ and notification/ACK history. `snapshot` is optional diagnostic output only;
101
+ it never sends a notice or becomes task/control truth. Snapshot may contain
102
+ sensitive output: request only when relevant, do not republish it by default.
103
+
104
+ An agent without a live App Server native thread may use local project
105
+ `list/status/snapshot` without registering a fake peer. Initialization and
106
+ queries explicitly report `notification_channel: none`: no push channel exists
107
+ for that observer. Check the mailbox in `status` yourself; do not wait for an
108
+ automatic completion notification. This is not a quality gate or a reason to
109
+ stop independent work. Mutating parent operations retain authenticated
110
+ ownership checks.
111
+
112
+ The child uses the injected `appsdk-subagent` MCP: `collab_init`, then
113
+ `collab_subagent` with `action=ready, id=<id>`. The launcher forwards the live
114
+ Codex App Server native-thread binding automatically; do not ask the user to
115
+ set environment variables. Use MCP, not sandboxed shell registration. Only its
116
+ bound identity may report ready. It accepts a dispatched task with `action=working`, manages its
117
+ own task/worktree lifecycle, sends results to the parent, and calls `ready`
118
+ when done. Repeated idle reports are no-ops. Remain idle, not an ACK/poll loop.
119
+ Task progress stays in Collab task records; no second task queue exists here.
120
+ Before assigned execution, use the same `appsdk bug intake --input <json>`
121
+ contract or the parent's returned `issue_id`; no ID means no governed
122
+ completion claim. Read-only conversation stays outside intake.
123
+
124
+ Only the creating parent may send/close; a user-requested early close may
125
+ interrupt work, but never deletes worktrees or marks tasks complete. Closing
126
+ uses the exact registered peer identity. It does not stop the project daemon.
127
+ Daemon restart replays records without automatically respawning or redispatching.
128
+ If startup was interrupted, preserve the record/session and inspect status;
129
+ do not reuse its ID to create another process.
130
+
131
+ Upgrade: install reviewed Collab and AppSDK releases, then `collab down` /
132
+ `collab up` per already-running project. No migration/reset/init of old tasks
133
+ is required. Preserve journals and running subworker sessions. Do not downgrade
134
+ to an older reader after new subworker events have been written to the journal.
@@ -0,0 +1,160 @@
1
+ ---
2
+ name: project-memory
3
+ description: "本地记忆: L1锚点+L2/L3入口+tag+相对路径; SQLite 搜 raw memory; 不是开发或规则升级门禁。"
4
+ ---
5
+
6
+ # Project memory
7
+
8
+ Use the independent `project-memory` command for memory only. It is available
9
+ at any time and is not a debug/develop or AppSDK rule-upgrade gate.
10
+
11
+ `memory/index.md` is the generated local index and curation source. It includes
12
+ short titles, tags, relative detail paths, and a fixed-size Skill description
13
+ candidate section. New details live in `memory/L1/`, `memory/L2/`, or
14
+ `memory/L3/`. Raw entries remain in
15
+ `memory/{plan,path,knowledge,lesson}.jsonl`; agents may read those Markdown and
16
+ raw files directly.
17
+
18
+ The project Skill `description` is the agent-visible resident index. During
19
+ initialization or an intentional refresh, carry the generated candidate lines
20
+ into that description manually: keep deduplicated level-1 anchors first, then
21
+ fill unused base slots with level 2 and finally level 3 entries. Each L2/L3
22
+ line states its kind, tags, and relative detail path. Do not invent paths or
23
+ rewrite Skill text during an ordinary memory write. Legacy `memory/details/`
24
+ remains readable for import compatibility but is not a new output location.
25
+
26
+ ## Review levels
27
+
28
+ - New CLI entries default to level 3 (`unreviewed`).
29
+ - Level 2 is reviewed and reusable; level 1 is reviewed and critical.
30
+ - Only a real review with evidence may promote an entry. Use `promote` or a
31
+ run-note `memory_review`; ordinary writes cannot self-assign level 1/2.
32
+ - Categories (`plan`, `path`, `knowledge`, `lesson`) describe content, not
33
+ review level. Tags are retrieval/classification features; one entry may have
34
+ multiple tags.
35
+
36
+ Classify every durable entry as exactly one of:
37
+
38
+ - `plan`: project goal, architecture, owner, boundaries, constraints.
39
+ - `path`: node, edge, flow, checklist, or execution rule.
40
+ - `knowledge`: one discrete fact, contract, function, resource, or setting.
41
+ - `lesson`: verified historical experience, root cause, pitfall, or resolution.
42
+
43
+ ## Fixed query order
44
+
45
+ Keep result groups in this order: L1 anchors, exact ID, node/function/resource,
46
+ category/tag, declared relations, lesson references, FTS5 keywords, WeMM
47
+ semantic candidates, then importance and updated time. Semantic candidates are
48
+ advisory and never change explicit flow edges or active process revisions.
49
+
50
+ ## Commands
51
+
52
+ ```text
53
+ project-memory query <text> [project]
54
+ project-memory get <memory-id> [project]
55
+ project-memory entry --title <title> --text <content> [--tag <tag>]
56
+ project-memory entry --id <id> --category <category> --title <title> --text <content> [--tag <tag>]
57
+ project-memory query --tag <tag> [text] [project]
58
+ project-memory review --run <run-id>
59
+ project-memory promote --id <id> --level <1|2> --evidence <ref>
60
+ project-memory migrate [project]
61
+ project-memory import [project] [--global]
62
+ project-memory reentry [project] --run <run-id>
63
+ project-memory index
64
+ project-memory export
65
+ project-memory compact
66
+ project-memory verify
67
+ ```
68
+
69
+ The title+content `entry` path is the one-shot writer: one invocation appends
70
+ the raw event, atomically regenerates its detail Markdown, updates the title
71
+ index, and rebuilds the SQLite projection. It defaults to level 3 and is
72
+ idempotent by generated ID. Do not write raw, detail, or index files separately
73
+ for a normal entry. If a projection step is interrupted, rerun `index`/`export`
74
+ instead of submitting the entry again.
75
+ `review` is the task-end write-back path. It checks run notes, deduplicates,
76
+ classifies, preserves source references and tag unions, and updates the
77
+ rebuildable index. A review without an evidence-backed `memory_review` remains
78
+ level 3. Global promotion is explicit (`--global` on an entry); a project
79
+ review never writes global memory.
80
+
81
+ `compact` only compacts the rebuildable projection. It never rewrites, deletes,
82
+ or drops events from the JSONL sources. The effective node is the last event
83
+ for an ID with monotonic tag/source-reference/relation unions; changing an ID
84
+ across categories is rejected.
85
+
86
+ `index`/`export` is the raw-to-Markdown compatibility bridge: it regenerates
87
+ `memory/index.md` and level-specific detail files without deleting or rewriting
88
+ JSONL. `import` is the reverse bridge for an intentionally edited exported
89
+ detail. It accepts only the marked AppSDK Markdown format (and the previous
90
+ exported detail format), validates all detail files first, appends changed
91
+ entries to the categorized JSONL source, and rebuilds the index. Repeating it
92
+ without a Markdown change is a no-op. A detail is not a second truth store:
93
+ the JSONL event history remains canonical, and direct Markdown edits
94
+ to existing IDs take effect through explicit `import`.
95
+
96
+ ### Handwritten L3 additions (automatic)
97
+
98
+ Write `memory/L3/<id>.md` using this format; filename and metadata ID must match:
99
+
100
+ ```markdown
101
+ <!-- project-memory:v1 {"id":"cache-key-rule","category":"knowledge","tags":["cache","debug"]} -->
102
+
103
+ # Cache keys include tenant
104
+
105
+ Include the tenant ID in cache keys to isolate tenant data.
106
+ <!-- project-memory:end -->
107
+ ```
108
+
109
+ The next `query`, `get`, `index`, `export`, or `verify` imports new IDs into
110
+ JSONL and SQLite automatically, even when SQLite already exists. No daemon,
111
+ separate registration, or explicit import is needed for additions. Projection
112
+ rebuilds also ingest pending additions before exporting. Repeated access adds
113
+ no duplicate event. New entries are always L3/unreviewed; handwritten review
114
+ claims are ignored. Missing category defaults to `knowledge`.
115
+
116
+ For an existing ID, use `import` immediately after editing and before any
117
+ projection rebuild. Automatic ingestion is additions-only, not conflict
118
+ resolution between an edited detail and raw history. Invalid files fail with
119
+ an actionable error and remain on disk; repair their format, do not delete
120
+ memory to make a query pass. New L1/L2 files are not automatically ingested.
121
+
122
+ Compatibility paths:
123
+
124
+ ```text
125
+ legacy entries.jsonl/memories.jsonl --migrate--> categorized JSONL
126
+ categorized JSONL --index|export--> index.md + L1/L2/L3/<id>.md
127
+ edited marked detail --import--> categorized JSONL event + rebuilt projection
128
+ ```
129
+
130
+ Malformed, unmarked, duplicate-ID, or conflicting details fail explicitly;
131
+ they are never guessed into memory. `import --global` applies the same rule to
132
+ the global detail directory.
133
+
134
+ ## Migration and re-entry
135
+
136
+ Migration is explicit and source-preserving. `project-memory migrate` accepts
137
+ the supported legacy flat sources (`memory/entries.jsonl` or
138
+ `memory/memories.jsonl`), validates every line before writing, records a
139
+ versioned `memory/migration.json` marker, appends new entries or
140
+ metadata-completing events when the effective version lacks incoming tags or
141
+ source references, and rebuilds the SQLite projection. The legacy source is
142
+ never deleted or overwritten. A marker in `in_progress` can be run again with
143
+ the same source digest; completed migration is idempotent. A changed source or
144
+ an ID/content conflict is reported instead of silently replacing project
145
+ truth.
146
+
147
+ Re-entry may ingest new L3 details when it reads memory and rebuild stale or
148
+ missing SQLite projections. Run
149
+ `project-memory reentry [project] --run <run-id>` after an interruption (the
150
+ project path is optional and may also follow the `--run` value). It keeps the
151
+ same run ID, reads the last note as `resume_from`, checks the migration marker,
152
+ rebuilds a missing index, and returns L1 anchors plus bounded `next_queries`
153
+ for the next L2/L3 lookup. If migration is absent or unfinished, re-entry is
154
+ blocked with the exact migration command; it never invents a new run or state.
155
+
156
+ The WeMM adapter is optional. Until a pinned local inference backend is
157
+ configured, it reports candidate-only RAG/semantic candidates and does not mock
158
+ semantic edges. Graph search uses declared and semantic relation edges returned
159
+ by `query`. Open the returned `detail_path` directly when the title is relevant;
160
+ do not copy full detail into the index.