@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.
- package/README.md +8 -2
- package/artifact.json +25 -0
- package/bin/appsdk +0 -0
- package/bin/project-memory +0 -0
- package/package.json +24 -4
- package/skills/appsdk-migration/SKILL.md +429 -0
- package/skills/appsdk-project-governance/SKILL.md +664 -0
- package/skills/appsdk-project-governance/agents/openai.yaml +4 -0
- package/skills/appsdk-project-governance/appsdk-guidance.json +201 -0
- package/skills/appsdk-project-governance/references/authoritative-review-template.md +230 -0
- package/skills/appsdk-project-governance/references/bootstrap-migration.md +482 -0
- package/skills/appsdk-project-governance/references/command-surface.md +111 -0
- package/skills/appsdk-project-governance/references/contracts-and-failures.md +74 -0
- package/skills/appsdk-project-governance/references/development-debug.md +86 -0
- package/skills/appsdk-project-governance/references/goal-prompt.md +69 -0
- package/skills/appsdk-project-governance/references/init-prompts.md +212 -0
- package/skills/appsdk-project-governance/references/process-control-harness.md +162 -0
- package/skills/appsdk-project-governance/references/review-delivery.md +127 -0
- package/skills/appsdk-project-governance/references/state-paths.md +157 -0
- package/skills/appsdk-project-governance/references/subagents-config.md +134 -0
- package/skills/project-memory/SKILL.md +160 -0
|
@@ -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.
|