@rubytech/create-maxy-code 0.1.501 → 0.1.502
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/package.json +1 -1
- package/payload/platform/docs/superpowers/plans/2026-07-25-task-1974-uploads-intake-inbox.md +235 -0
- package/payload/platform/docs/superpowers/plans/2026-07-25-task-1976-intra-folder-hygiene.md +215 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +2 -2
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +7 -0
- package/payload/platform/plugins/docs/references/internals.md +1 -1
- package/payload/platform/templates/account-schema/SCHEMA.md +36 -1
- package/payload/platform/templates/specialists/agents/data-manager.md +4 -2
- package/payload/server/public/activity.html +5 -5
- package/payload/server/public/assets/AdminLoginScreens-Bv_bKKeL.js +1 -0
- package/payload/server/public/assets/AdminShell-Gq8DU_ig.js +2 -0
- package/payload/server/public/assets/{activity-CVdVSw5V.js → activity-DZFYDHNA.js} +1 -1
- package/payload/server/public/assets/{admin-If1QLlS3.js → admin-DLUOixl6.js} +1 -1
- package/payload/server/public/assets/{bot-8b26IlQY.js → bot-CrEhKW1l.js} +1 -1
- package/payload/server/public/assets/{browser-F40DXfKA.js → browser-Bt4-LKLU.js} +1 -1
- package/payload/server/public/assets/{calendar-DZiHiBwV.js → calendar-D0qIvLUR.js} +1 -1
- package/payload/server/public/assets/chat-geSkx0j2.js +1 -0
- package/payload/server/public/assets/chevron-left-CQ8rcBoO.js +1 -0
- package/payload/server/public/assets/chevron-right-CSRSqblN.js +1 -0
- package/payload/server/public/assets/clock-B7Ba8AZL.js +1 -0
- package/payload/server/public/assets/data-BdlGqjKM.js +1 -0
- package/payload/server/public/assets/{file-text-B1HjPFbM.js → file-text-BpLcZKld.js} +1 -1
- package/payload/server/public/assets/{graph-CIC-mgKR.js → graph-HB0199x-.js} +3 -3
- package/payload/server/public/assets/{graph-labels-BnpHCHaQ.js → graph-labels-Bx19ZYvJ.js} +1 -1
- package/payload/server/public/assets/{maximize-2-BL7QVTcQ.js → maximize-2-BhR-Ec21.js} +1 -1
- package/payload/server/public/assets/operator-DejfJlvi.js +1 -0
- package/payload/server/public/assets/page-DomkejEB.js +32 -0
- package/payload/server/public/assets/page-FnCmAeHc.js +1 -0
- package/payload/server/public/assets/{public-BI21tOkm.js → public-Be_Galv6.js} +1 -1
- package/payload/server/public/assets/{rotate-ccw-C_20Bc3E.js → rotate-ccw-D9qOBLig.js} +1 -1
- package/payload/server/public/assets/{routines-Ci3N8wqV.js → routines-lGiYaMiX.js} +1 -1
- package/payload/server/public/assets/{skills-CiflzOko.js → skills-D9nWOqoz.js} +1 -1
- package/payload/server/public/assets/{tasks-DC2Yf2Ev.js → tasks-Cyc1EfLA.js} +1 -1
- package/payload/server/public/assets/{time-entry-format-CNcjs2HV.js → time-entry-format-RkCW7hKu.js} +1 -1
- package/payload/server/public/assets/{triangle-alert-CngnWtjD.js → triangle-alert-k8ulav-N.js} +1 -1
- package/payload/server/public/assets/{useCopyFeedback-DZ9Bw5CI.js → useCopyFeedback-DN1WA5vU.js} +1 -1
- package/payload/server/public/assets/useSubAccountSwitcher-fvBunpOC.css +1 -0
- package/payload/server/public/assets/useSubAccountSwitcher-iQGqNJhI.js +9 -0
- package/payload/server/public/assets/useVoiceRecorder-v--TIxaM.js +2 -0
- package/payload/server/public/assets/{wrench-dky2-13x.js → wrench-CKhz8KnQ.js} +1 -1
- package/payload/server/public/browser.html +4 -4
- package/payload/server/public/calendar.html +7 -7
- package/payload/server/public/chat.html +14 -14
- package/payload/server/public/data.html +11 -11
- package/payload/server/public/graph.html +9 -9
- package/payload/server/public/index.html +15 -15
- package/payload/server/public/operator.html +15 -15
- package/payload/server/public/public.html +14 -14
- package/payload/server/public/routines.html +6 -6
- package/payload/server/public/skills.html +5 -5
- package/payload/server/public/tasks.html +6 -6
- package/payload/server/server.js +840 -748
- package/payload/server/public/assets/AdminLoginScreens-C3LZOPIY.js +0 -1
- package/payload/server/public/assets/AdminShell-BlbUNAPc.js +0 -2
- package/payload/server/public/assets/chat-uD28FVCS.js +0 -1
- package/payload/server/public/assets/chevron-left-lBxD57tD.js +0 -1
- package/payload/server/public/assets/chevron-right-C-lDig9Y.js +0 -1
- package/payload/server/public/assets/clock-DqRNsY40.js +0 -1
- package/payload/server/public/assets/data-BsFyBN85.js +0 -1
- package/payload/server/public/assets/operator-B62h_TaC.js +0 -1
- package/payload/server/public/assets/page-BUUBseJZ.js +0 -32
- package/payload/server/public/assets/page-Bw-tYjw7.js +0 -1
- package/payload/server/public/assets/useSubAccountSwitcher-CHwQhkaI.js +0 -9
- package/payload/server/public/assets/useSubAccountSwitcher-yFQqnpQ8.css +0 -1
- package/payload/server/public/assets/useVoiceRecorder-C3G6aqZr.js +0 -2
package/package.json
CHANGED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Task 1974 — uploads/ intake inbox Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Reclassify the account `uploads/` directory from tool-owned scratch to a temporary intake inbox, and add a `stranded-intake` reconcile count so a node file-reference left pointing into `uploads/` is visible.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Doctrine plus audit change, no code path change. Three prose files are edited (`SCHEMA.md`, `data-manager.md`, `internals.md`), then the `platform-architecture` SKILL.md twin is regenerated from the docs corpus so the no-drift gate passes. Detection-only, mirroring the outbound `output/` rule landed by task 1930.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Markdown doctrine files; Node regen scripts (`docs/scripts/copy-docs.mjs`, `maxy-code/scripts/assemble-architecture-skill.mjs`); the drift gate `maxy-code/platform/scripts/check-architecture-skill-no-drift.mjs`; the bash test `fs-schema-guard.test.sh`.
|
|
10
|
+
|
|
11
|
+
## Global Constraints
|
|
12
|
+
|
|
13
|
+
- Zero em-dashes in all shipped prose.
|
|
14
|
+
- The 1930 outbound rule must survive intact: the `output/` promote-out sentence and the `scratch-refs` / `stranded` counts stay present. `stranded-intake` is appended to the output contract, never a rename of `stranded`.
|
|
15
|
+
- `uploads` stays in the `allowed-top-level` block of SCHEMA.md (files still land there).
|
|
16
|
+
- The write-path guard, the admin-UI upload handler, and `memory-ingest` `sourcePath` behaviour are unchanged.
|
|
17
|
+
- Reconcile output contract after this task: `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R`.
|
|
18
|
+
- Paths are relative to the `maxy-code/` subtree root inside the worktree.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
### Task 1: SCHEMA.md — reclassify uploads/ as intake inbox
|
|
23
|
+
|
|
24
|
+
**Files:**
|
|
25
|
+
- Modify: `platform/templates/account-schema/SCHEMA.md:31-39`
|
|
26
|
+
|
|
27
|
+
**Interfaces:**
|
|
28
|
+
- Produces: the doctrine text data-manager.md and internals.md refer to. No code symbols.
|
|
29
|
+
|
|
30
|
+
- [ ] **Step 1: Remove `uploads/` from the "recreated on the next write" list.**
|
|
31
|
+
|
|
32
|
+
At `SCHEMA.md:36-39`, change the list so `uploads/` is no longer among tool-owned rebuilt dirs:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
The internal structure of these is owned by the writing tool and is recreated on
|
|
36
|
+
the next write: `url-get/`, `output/`, `generated/`, `extracted/`,
|
|
37
|
+
any published/served tree (`sites/`, `public/`), `agents/`, `specialists/`, and
|
|
38
|
+
platform-internal areas (`cache/`, `secrets/`, `state/`, `logs/`, `tmp/`).
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- [ ] **Step 2: Add the intake-inbox rule paragraph.**
|
|
42
|
+
|
|
43
|
+
Immediately after the `output/` promote-out paragraph (ends at `SCHEMA.md:34`), insert a new paragraph. It states uploads is a temporary intake inbox, a file is promoted to its canonical bucket when its node is created, no persisted graph reference points into `uploads/`, and the per-`<attachmentId>` reason it is safe to move out of (unlike `output/`):
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
`uploads/` is a temporary intake inbox, not rebuilt scratch. A file lands at
|
|
47
|
+
`uploads/<attachmentId>/` on upload and is promoted to its canonical entity
|
|
48
|
+
bucket when its graph node is created: a Person or Organization file to
|
|
49
|
+
`contacts/<name>/`, a Project file to `projects/<name>/`, anything else to
|
|
50
|
+
`documents/`. A persisted graph reference must never point into `uploads/`.
|
|
51
|
+
Unlike `output/`, each upload writes its own `uploads/<attachmentId>/` dir and no
|
|
52
|
+
tool walks or rebuilds the subtree, so promoting a file out of it through the
|
|
53
|
+
`data-manager` specialist is safe.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
- [ ] **Step 3: Verify the edit.**
|
|
57
|
+
|
|
58
|
+
Run:
|
|
59
|
+
```bash
|
|
60
|
+
cd platform/templates/account-schema
|
|
61
|
+
# uploads no longer in the recreated-on-next-write list
|
|
62
|
+
awk '/recreated on/,/logs.*tmp/' SCHEMA.md | grep -c 'uploads/' | grep -qx 0 && echo "OK: uploads removed from scratch list"
|
|
63
|
+
# intake-inbox rule present
|
|
64
|
+
grep -q 'temporary intake inbox' SCHEMA.md && echo "OK: intake rule present"
|
|
65
|
+
# uploads still allowed-top-level
|
|
66
|
+
grep -A40 'allowed-top-level' SCHEMA.md | grep -qx 'uploads' && echo "OK: uploads still allowed-top-level"
|
|
67
|
+
# 1930 output/ rule survives
|
|
68
|
+
grep -q 'promoted out of `output/`' SCHEMA.md && echo "OK: 1930 output rule intact"
|
|
69
|
+
# zero em-dashes in this file
|
|
70
|
+
! grep -q '—' SCHEMA.md && echo "OK: no em-dash"
|
|
71
|
+
```
|
|
72
|
+
Expected: all five OK lines.
|
|
73
|
+
|
|
74
|
+
- [ ] **Step 4: Commit.**
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
git add platform/templates/account-schema/SCHEMA.md
|
|
78
|
+
git commit -m "task: reclassify uploads/ as intake inbox in account SCHEMA.md (1974)"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
### Task 2: data-manager.md — reconcile case (e), walk uploads/, promotion permission, output contract
|
|
84
|
+
|
|
85
|
+
**Files:**
|
|
86
|
+
- Modify: `platform/templates/specialists/agents/data-manager.md:24` (reconcile brief), `:30` (output contract), and the "What success looks like" area for the promotion permission.
|
|
87
|
+
|
|
88
|
+
**Interfaces:**
|
|
89
|
+
- Consumes: the SCHEMA.md intake-inbox rule from Task 1.
|
|
90
|
+
- Produces: the `stranded-intake=R` field that internals.md documents in Task 3.
|
|
91
|
+
|
|
92
|
+
- [ ] **Step 1: Add reconcile case (e) and include uploads/ in the walk.**
|
|
93
|
+
|
|
94
|
+
At `data-manager.md:24`, extend the counted list. After case (d), add case (e): a graph file-reference that resolves into `uploads/`, the inbound intake mirror of the `output/` scratch case. State that the walk now includes `uploads/` (a file under `uploads/` with no referencing node folds into `unreachable`). Exact appended clause inside the sentence that enumerates (a) to (d):
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
, and (e) graph file-references that resolve into the `uploads/` intake inbox,
|
|
98
|
+
which is a temporary landing area a file should have been promoted out of when
|
|
99
|
+
its node was created. The walk now includes `uploads/`; a file under `uploads/`
|
|
100
|
+
that no node references counts under (a) unreachable.
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
- [ ] **Step 2: Add the stewardship promotion permission for uploads/.**
|
|
104
|
+
|
|
105
|
+
In "## What success looks like" (after `data-manager.md:16`, the paired-move paragraph), add a sentence permitting promotion out of `uploads/`:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
- A file in the `uploads/` intake inbox whose graph node exists is promoted to
|
|
109
|
+
its canonical bucket (Person or Organization to `contacts/<name>/`, Project to
|
|
110
|
+
`projects/<name>/`, else `documents/`), paired with a `database-operator`
|
|
111
|
+
`sourcePath` update in the same pass, exactly as any other move.
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
- [ ] **Step 3: Change the output contract.**
|
|
115
|
+
|
|
116
|
+
At `data-manager.md:30`, change the reconcile summary line:
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
For the reconcile audit: `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R`.
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
- [ ] **Step 4: Verify the edit.**
|
|
123
|
+
|
|
124
|
+
Run:
|
|
125
|
+
```bash
|
|
126
|
+
cd platform/templates/specialists/agents
|
|
127
|
+
grep -q 'stranded-intake=R' data-manager.md && echo "OK: contract has stranded-intake"
|
|
128
|
+
grep -q 'scratch-refs=P stranded=Q' data-manager.md && echo "OK: 1930 fields survive"
|
|
129
|
+
grep -q '(e) graph file-references that resolve into the `uploads/`' data-manager.md && echo "OK: case e present"
|
|
130
|
+
grep -q 'promoted to' data-manager.md && grep -q 'sourcePath` update' data-manager.md && echo "OK: promotion permission present"
|
|
131
|
+
! grep -q '—' data-manager.md && echo "OK: no em-dash"
|
|
132
|
+
```
|
|
133
|
+
Expected: five OK lines.
|
|
134
|
+
|
|
135
|
+
- [ ] **Step 5: Commit.**
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
git add platform/templates/specialists/agents/data-manager.md
|
|
139
|
+
git commit -m "task: data-manager reconcile counts uploads/ intake drift as stranded-intake (1974)"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
### Task 3: internals.md — document the reclassification and the stranded-intake count
|
|
145
|
+
|
|
146
|
+
**Files:**
|
|
147
|
+
- Modify: `platform/plugins/docs/references/internals.md:411`
|
|
148
|
+
|
|
149
|
+
**Interfaces:**
|
|
150
|
+
- Consumes: the reconcile contract from Task 2.
|
|
151
|
+
- Produces: the corpus text the architecture SKILL.md twin regenerates from in Task 4.
|
|
152
|
+
|
|
153
|
+
- [ ] **Step 1: Append the intake-inbox rule to the placement paragraph.**
|
|
154
|
+
|
|
155
|
+
At `internals.md:411`, the sentence currently ends: "...is counted by the `data-manager` reconcile audit (`scratch-refs`, `stranded`); making that audit run on a standing periodic cadence is a filed follow-up." Extend it with the inbound mirror. Append after the `scratch-refs`/`stranded` clause:
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
The inbound mirror is the `uploads/` intake inbox: an uploaded file lands at `uploads/<attachmentId>/` and is promoted to its canonical entity bucket when its graph node is created, so a persisted node reference resolving into `uploads/` is intake drift, counted by the same reconcile audit as `stranded-intake`. Unlike `output/`, `uploads/` is never rebuilt by a tool, so the `data-manager` may promote a file out of it. The reconcile output contract is `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R`.
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
- [ ] **Step 2: Verify the edit.**
|
|
162
|
+
|
|
163
|
+
Run:
|
|
164
|
+
```bash
|
|
165
|
+
grep -q 'stranded-intake' platform/plugins/docs/references/internals.md && echo "OK: internals mentions count"
|
|
166
|
+
grep -q 'intake inbox' platform/plugins/docs/references/internals.md && echo "OK: internals mentions reclassification"
|
|
167
|
+
! grep -q '—' platform/plugins/docs/references/internals.md && echo "OK: no em-dash added"
|
|
168
|
+
```
|
|
169
|
+
Expected: three OK lines. (The last check should already pass before the edit; keep the added prose em-dash-free.)
|
|
170
|
+
|
|
171
|
+
- [ ] **Step 3: Commit.**
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
git add platform/plugins/docs/references/internals.md
|
|
175
|
+
git commit -m "task: internals.md documents uploads/ intake inbox and stranded-intake count (1974)"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
### Task 4: Regenerate the architecture skill twin and pass the gates
|
|
181
|
+
|
|
182
|
+
**Files:**
|
|
183
|
+
- Modify (generated): `platform/plugins/admin/skills/platform-architecture/SKILL.md`
|
|
184
|
+
- Run: `docs/scripts/copy-docs.mjs`, `maxy-code/scripts/assemble-architecture-skill.mjs`, `platform/scripts/check-architecture-skill-no-drift.mjs`, `platform/plugins/admin/hooks/__tests__/fs-schema-guard.test.sh`
|
|
185
|
+
|
|
186
|
+
**Interfaces:**
|
|
187
|
+
- Consumes: the edited internals.md from Task 3.
|
|
188
|
+
- Produces: a SKILL.md byte-equal to what the gate regenerates.
|
|
189
|
+
|
|
190
|
+
- [ ] **Step 1: Regenerate the corpus and the skill twin.**
|
|
191
|
+
|
|
192
|
+
Run from the worktree repo root:
|
|
193
|
+
```bash
|
|
194
|
+
node docs/scripts/copy-docs.mjs
|
|
195
|
+
node maxy-code/scripts/assemble-architecture-skill.mjs --brand maxy-code
|
|
196
|
+
```
|
|
197
|
+
Expected: `[copy-docs]` and `[platform-arch-assemble] op=write` lines, no error.
|
|
198
|
+
|
|
199
|
+
- [ ] **Step 2: Run the drift gate.**
|
|
200
|
+
|
|
201
|
+
Run:
|
|
202
|
+
```bash
|
|
203
|
+
node maxy-code/platform/scripts/check-architecture-skill-no-drift.mjs --brand maxy-code
|
|
204
|
+
```
|
|
205
|
+
Expected: exit 0, no drift reported. If it reports drift, the regen in Step 1 did not run or the SKILL.md was not re-written; re-run Step 1.
|
|
206
|
+
|
|
207
|
+
- [ ] **Step 3: Run the write-guard test (regression boundary).**
|
|
208
|
+
|
|
209
|
+
Run:
|
|
210
|
+
```bash
|
|
211
|
+
bash maxy-code/platform/plugins/admin/hooks/__tests__/fs-schema-guard.test.sh
|
|
212
|
+
```
|
|
213
|
+
Expected: all assertions pass. The guard is unchanged; `uploads/` is still an allowed write, so this stays green.
|
|
214
|
+
|
|
215
|
+
- [ ] **Step 4: Commit the regenerated twin (and any corpus artefact the gate expects committed).**
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
git add platform/plugins/admin/skills/platform-architecture/SKILL.md
|
|
219
|
+
git status --porcelain docs/public
|
|
220
|
+
# stage docs/public/llms-full.*.txt only if it is a tracked artefact that changed
|
|
221
|
+
git commit -m "task: regenerate platform-architecture skill twin for 1974"
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Land (Phase 6 handles this — not an implementation task)
|
|
227
|
+
|
|
228
|
+
LANES.md and task-file archival are done in Phase 6c of the sprint, not here. The task's "LANES Ready row" line describes the pre-implementation state; because this sprint implements and archives in one motion, the end state is: task file under `.tasks/archive/`, no Ready row referencing 1974, and the archive sentence naming 1974. This is a deliberate deviation from the task's literal LANES line, recorded in Plan Conformity.
|
|
229
|
+
|
|
230
|
+
## Self-Review
|
|
231
|
+
|
|
232
|
+
- **Spec coverage:** SCHEMA.md reclassification (Task 1), data-manager.md case (e) + walk + promotion + contract (Task 2), internals.md + twin regen (Tasks 3-4), LANES (Phase 6c). Every in-scope item maps to a task.
|
|
233
|
+
- **Out of scope confirmed untouched:** no auto-promotion hook, no cadence (1931), no CC-native uploads reach, no write-guard edit, no ingest-path edit.
|
|
234
|
+
- **Type consistency:** the single shared token is the output-contract string; it reads `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R` identically in Tasks 2 and 3.
|
|
235
|
+
- **Placeholder scan:** none; every edit carries its literal text.
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# Task 1976 Intra-folder Filing Hygiene Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Teach the `data-manager` reconcile audit to count three intra-folder drift kinds (superseded versions, format twins, stray subfolders) and state the three governing rules in `SCHEMA.md`, `data-manager.md`, and `internals.md`, so version and format sprawl becomes visible before a cleanup is asked for.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Detection-and-doctrine only, matching the 1930/1974 precedent. Three markdown source files gain the rules and counts; the `platform-architecture/SKILL.md` twin is regenerated from `internals.md` by the assembler, never hand-edited. No new write-time guard, no automatic deletion.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Markdown templates, Node ESM regen scripts (`docs/scripts/copy-docs.mjs`, `maxy-code/scripts/assemble-architecture-skill.mjs`), Bash test harness (`fs-schema-guard.test.sh`), drift gate (`check-architecture-skill-no-drift.mjs`).
|
|
10
|
+
|
|
11
|
+
## Global Constraints
|
|
12
|
+
|
|
13
|
+
- Zero em-dashes in shipped prose (use commas, colons, or full stops).
|
|
14
|
+
- Detection-only: the reconcile audit counts, it never removes. Removal is a stewardship dispatch under operator direction (deletion is destructive).
|
|
15
|
+
- The three new fields are **appended** to the output contract, never substituted: `scratch-refs`, `stranded`, and `stranded-intake` all survive.
|
|
16
|
+
- The no-subfolder rule is scoped to `projects/<name>/` and `contacts/<name>/` only. `documents/` is allowed one document-folder deep (`documents/<doc>/file`) and is out of scope for the subfolder rule.
|
|
17
|
+
- Version-group definition: `<base>.ext` and `<base>-vN.ext` sharing basename stem and extension are versions of one deliverable.
|
|
18
|
+
- Format-twin definition: same basename where a delivered `.pdf` sits beside its source render `.html`/`.md`; count the source renders whose delivered twin exists.
|
|
19
|
+
- The reconcile has no automated harness (it runs as a Sonnet agent). Verification of the counts is manual on a seeded folder; the automated gates that must stay green are `fs-schema-guard.test.sh` and `check-architecture-skill-no-drift.mjs`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
### Task 1: SCHEMA.md — Intra-folder hygiene section
|
|
24
|
+
|
|
25
|
+
**Files:**
|
|
26
|
+
- Modify: `platform/templates/account-schema/SCHEMA.md` (insert a new `## Intra-folder hygiene` section between `## Naming convention` and `## Tool-owned`)
|
|
27
|
+
|
|
28
|
+
**Interfaces:**
|
|
29
|
+
- Produces: the three named rules (current-version-only, one-canonical-format, no-subfolder) that Task 2 and Task 3 reference by name.
|
|
30
|
+
|
|
31
|
+
- [ ] **Step 1: Insert the section** after the Naming convention section (currently ending at line 27), before `## Tool-owned`:
|
|
32
|
+
|
|
33
|
+
```markdown
|
|
34
|
+
## Intra-folder hygiene
|
|
35
|
+
|
|
36
|
+
The operator-data buckets hold one current copy of each deliverable, in one
|
|
37
|
+
canonical format, with no subtree. Three rules keep them that way; the standing
|
|
38
|
+
reconcile counts any that predate them, and `data-manager` clears them on a
|
|
39
|
+
stewardship dispatch.
|
|
40
|
+
|
|
41
|
+
- **Current version only.** `<base>.ext` and `<base>-vN.ext` (for example
|
|
42
|
+
`charlotte-deck.pdf` and `charlotte-deck-v2.pdf` through
|
|
43
|
+
`charlotte-deck-v6.pdf`) are versions of one deliverable, not separate files.
|
|
44
|
+
Keep the newest; the superseded copies are removed through `data-manager`.
|
|
45
|
+
- **One canonical format.** A delivered `.pdf` and its source render sharing the
|
|
46
|
+
same basename (`charlotte-deck.html` beside `charlotte-deck.pdf`,
|
|
47
|
+
`invoice-rbt-2026-005.html` beside `invoice-rbt-2026-005.pdf`) are one
|
|
48
|
+
deliverable in two formats. The pdf is the deliverable; the `.html` or `.md`
|
|
49
|
+
render that produced it is not a second one and is removed through
|
|
50
|
+
`data-manager`.
|
|
51
|
+
- **No subfolder.** No folder nests under `projects/<name>/` or
|
|
52
|
+
`contacts/<name>/`; files live directly inside the entity folder. This is the
|
|
53
|
+
flat rule from the buckets above, restated as a standing invariant: the write
|
|
54
|
+
guard blocks the depth as you create it, and the reconcile counts any subtree
|
|
55
|
+
that predates the guard or was created off-path.
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
- [ ] **Step 2: Verify the section reads and has no em-dashes**
|
|
59
|
+
|
|
60
|
+
Run: `grep -n 'Intra-folder hygiene' platform/templates/account-schema/SCHEMA.md && ! grep -n '—' platform/templates/account-schema/SCHEMA.md && echo "no em-dash"`
|
|
61
|
+
Expected: the heading line prints, then `no em-dash`.
|
|
62
|
+
|
|
63
|
+
- [ ] **Step 3: Verify the write guard is untouched (green baseline holds)**
|
|
64
|
+
|
|
65
|
+
Run: `bash platform/plugins/admin/hooks/__tests__/fs-schema-guard.test.sh 2>&1 | tail -1`
|
|
66
|
+
Expected: `----- 22 passed, 0 failed -----`
|
|
67
|
+
|
|
68
|
+
- [ ] **Step 4: Commit**
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
git add platform/templates/account-schema/SCHEMA.md
|
|
72
|
+
git commit -m "task: SCHEMA.md states intra-folder hygiene rules (1976)"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### Task 2: data-manager.md — three counts, output contract, stewardship
|
|
78
|
+
|
|
79
|
+
**Files:**
|
|
80
|
+
- Modify: `platform/templates/specialists/agents/data-manager.md` (reconcile brief at line 25, output contract at line 31, "What success looks like" at line 17)
|
|
81
|
+
|
|
82
|
+
**Interfaces:**
|
|
83
|
+
- Consumes: the three rule names from Task 1.
|
|
84
|
+
- Produces: the output-contract line `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R versioned=S format-twins=T stray-subdir=U` that Task 3 mirrors verbatim.
|
|
85
|
+
|
|
86
|
+
- [ ] **Step 1: Extend the reconcile brief** (line 25). Insert immediately before `Move nothing, dispatch nothing.`:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
Then, per operator-data entity folder (`projects/<name>/`, `contacts/<name>/`), count three intra-folder drifts from disk structure alone, no graph resolution needed: (f) files in a version group, where `<base>.ext` and `<base>-vN.ext` share a basename stem and extension and all but the newest are superseded, counting every superseded copy as `versioned`; (g) format twins, a source-render file (`.html`, `.md`) whose delivered `.pdf` twin of the same basename sits in the same folder, counting each such render as `format-twins`; (h) stray subfolders nested under an entity folder, which the flat rule forbids, counting each subfolder as `stray-subdir`.
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- [ ] **Step 2: Extend the output contract** (line 31). Change the reconcile-audit string from:
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
`unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R`
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
to:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
`unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R versioned=S format-twins=T stray-subdir=U`
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
- [ ] **Step 3: Add the stewardship bullet** to "What success looks like", immediately after the `uploads/` promotion bullet (line 17):
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
- Superseded versions and redundant format twins are removed, and a subfolder nested under `projects/<name>/` or `contacts/<name>/` is flattened or re-filed, when a stewardship brief asks for it. Each removal or move pairs with a `database-operator` reference update in the same pass, exactly as any other move: the surviving current render keeps the node reference, and a removed file's node is repointed or its reference dropped. Removal is destructive, so it happens only on an explicit stewardship dispatch, never in the read-only reconcile audit.
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- [ ] **Step 4: Verify the contract line and no em-dashes**
|
|
111
|
+
|
|
112
|
+
Run: `grep -c 'versioned=S format-twins=T stray-subdir=U' platform/templates/specialists/agents/data-manager.md && grep -o 'scratch-refs=P stranded=Q stranded-intake=R' platform/templates/specialists/agents/data-manager.md && ! grep '—' platform/templates/specialists/agents/data-manager.md && echo "no em-dash"`
|
|
113
|
+
Expected: `1`, then the preserved `scratch-refs=P stranded=Q stranded-intake=R` fragment, then `no em-dash`.
|
|
114
|
+
|
|
115
|
+
- [ ] **Step 5: Commit**
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
git add platform/templates/specialists/agents/data-manager.md
|
|
119
|
+
git commit -m "task: data-manager reconcile counts versioned/format-twins/stray-subdir (1976)"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### Task 3: internals.md — reconcile rules and contract string
|
|
125
|
+
|
|
126
|
+
**Files:**
|
|
127
|
+
- Modify: `platform/plugins/docs/references/internals.md` (the reconcile paragraph at line 411)
|
|
128
|
+
|
|
129
|
+
**Interfaces:**
|
|
130
|
+
- Consumes: the output-contract line from Task 2 (must match verbatim).
|
|
131
|
+
- Produces: the corpus source the assembler reads to regenerate the SKILL.md twin in Task 4.
|
|
132
|
+
|
|
133
|
+
- [ ] **Step 1: Insert the intra-folder description** into line 411, immediately before the final sentence `The reconcile output contract is ...`:
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
Beyond placement and intake, the same audit counts intra-folder sprawl inside each operator-data entity folder from disk structure alone: superseded version copies (`<base>.ext` and `<base>-vN.ext` are one deliverable, all but the newest counted `versioned`), format twins (a source `.html`/`.md` render kept beside its delivered `.pdf` of the same basename, counted `format-twins`), and subfolders nested under `projects/<name>/` or `contacts/<name>/` that the flat rule forbids (counted `stray-subdir`). These are read-only counts; removal or flattening happens only on a `data-manager` stewardship dispatch, each paired with a `database-operator` reference update.
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
- [ ] **Step 2: Update the contract string** in the same paragraph, from:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
The reconcile output contract is `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R`.
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
to:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
The reconcile output contract is `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R versioned=S format-twins=T stray-subdir=U`.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
- [ ] **Step 3: Verify the string matches Task 2 and no em-dashes in the changed region**
|
|
152
|
+
|
|
153
|
+
Run: `grep -c 'versioned=S format-twins=T stray-subdir=U' platform/plugins/docs/references/internals.md && grep -o 'counted `stray-subdir`' platform/plugins/docs/references/internals.md`
|
|
154
|
+
Expected: `1`, then `counted `stray-subdir``.
|
|
155
|
+
|
|
156
|
+
- [ ] **Step 4: Commit**
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
git add platform/plugins/docs/references/internals.md
|
|
160
|
+
git commit -m "task: internals.md documents intra-folder hygiene counts (1976)"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### Task 4: Regenerate the platform-architecture SKILL.md twin and gate it
|
|
166
|
+
|
|
167
|
+
**Files:**
|
|
168
|
+
- Regenerate (do not hand-edit): `platform/plugins/admin/skills/platform-architecture/SKILL.md`
|
|
169
|
+
|
|
170
|
+
**Interfaces:**
|
|
171
|
+
- Consumes: the edited `internals.md` from Task 3 (via the docs corpus).
|
|
172
|
+
|
|
173
|
+
- [ ] **Step 1: Rebuild the docs corpus** (mirrors internals.md into `docs/public/llms-full.<brand>.txt`). From the repo root:
|
|
174
|
+
|
|
175
|
+
Run: `cd "$(git rev-parse --show-toplevel)" && node docs/scripts/copy-docs.mjs 2>&1 | tail -2`
|
|
176
|
+
Expected: no error.
|
|
177
|
+
|
|
178
|
+
- [ ] **Step 2: Assemble both brand skills** (the maxy-code run writes SKILL.md):
|
|
179
|
+
|
|
180
|
+
Run: `cd "$(git rev-parse --show-toplevel)" && node maxy-code/scripts/assemble-architecture-skill.mjs --brand maxy-code && node maxy-code/scripts/assemble-architecture-skill.mjs --brand realagent-code`
|
|
181
|
+
Expected: `[platform-arch-assemble] op=write brand=maxy-code path=.../SKILL.md ...`.
|
|
182
|
+
|
|
183
|
+
- [ ] **Step 3: Run the drift gate**
|
|
184
|
+
|
|
185
|
+
Run: `cd maxy-code && node platform/scripts/check-architecture-skill-no-drift.mjs 2>&1 | tail -3`
|
|
186
|
+
Expected: `[check-architecture-skill-no-drift] ok brand=maxy-code (...)` and `... ok brand=realagent-code (...)`.
|
|
187
|
+
|
|
188
|
+
- [ ] **Step 4: Confirm the new fields reached the regenerated twin**
|
|
189
|
+
|
|
190
|
+
Run: `grep -c 'versioned=S format-twins=T stray-subdir=U' maxy-code/platform/plugins/admin/skills/platform-architecture/SKILL.md`
|
|
191
|
+
Expected: `1` (or more).
|
|
192
|
+
|
|
193
|
+
- [ ] **Step 5: Commit**
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
git add maxy-code/platform/plugins/admin/skills/platform-architecture/SKILL.md maxy-code/docs docs/public 2>/dev/null; git add -A
|
|
197
|
+
git commit -m "task: regenerate platform-architecture skill twin for 1976"
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Self-Review
|
|
203
|
+
|
|
204
|
+
**Spec coverage:**
|
|
205
|
+
- SCHEMA.md three rules → Task 1. ✓
|
|
206
|
+
- data-manager three counts + contract + stewardship → Task 2. ✓
|
|
207
|
+
- internals.md rules + counts → Task 3. ✓
|
|
208
|
+
- SKILL.md regenerated twin → Task 4. ✓
|
|
209
|
+
- LANES.md Ready row + archive → Phase 6 of the sprint (not a plan task; the sprint owns archive/LANES). ✓
|
|
210
|
+
|
|
211
|
+
**Placeholder scan:** every edit shows verbatim insert text. No TBD/TODO. ✓
|
|
212
|
+
|
|
213
|
+
**Type consistency:** the output-contract string is byte-identical in Task 2, Task 3, and the Task 4 grep: `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R versioned=S format-twins=T stray-subdir=U`. ✓
|
|
214
|
+
|
|
215
|
+
**Out of scope (deferred, no task needed here):** automatic deletion, a write-time guard for versions/twins, per-vertical canonical-format policy, the `uploads/` intake (1974, landed), the `/data` 524 (1975, archived), the `output/` promote-out counts (1930, landed). These are stated out-of-scope in the task brief, not dropped work.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: platform-architecture
|
|
3
3
|
description: Use when grounding any documented-surface claim about what Maxy ships — plugins, skills, specialists, install/deploy flows, internals. This is the install catalogue, not evidence of what is enabled on the current account. For install state on this account, call `capabilities-here`; for documented surface, cite the `Source:` URL inline.
|
|
4
|
-
content-hash: sha256:
|
|
4
|
+
content-hash: sha256:f78dfe81d9832fd7197627e1cf770c730bb2d16b4b640f1a47558e86acfe0db8
|
|
5
5
|
brand: maxy-code
|
|
6
6
|
product-name: Maxy
|
|
7
7
|
---
|
|
@@ -4354,7 +4354,7 @@ Standing rules the operator gives over a channel are `Preference` nodes. Two mec
|
|
|
4354
4354
|
|
|
4355
4355
|
**Observability.** `[preference-write] op=reconcile … mode=<reinforce|update|contradict|new> similarity=…` — a stream of `mode=new` for subjects that already exist is the duplicate-minting signature. `[preference-inject] op=inject channel=<wa|tg|web> injected=<N> owner=<8> source=<owner|no-owner|owner-error|fetch-error>` — injection selects only the account owner's admin preferences, so `source=owner injected=0` is a genuinely empty owner, `source=no-owner` is an account with no seeded owner (injects nothing, a missed owner seeding), and `injected=0 source=owner` on an account whose owner holds rules is the write-only regression re-appearing. `[preference-inject] op=reconcile accountId=… stored=… injected=…` — the standing reconciliation audit (claude-session-manager, 5-minute tick) flags any account whose stored active count diverges from what injection surfaces; injection now surfaces every stored active preference verbatim, so `stored == injected` is the healthy signal and any gap is a dropped-row regression (a reintroduced cap, filter, or truncation). A clean pass logs `op=reconcile drifted=0`, the no-event detector.
|
|
4356
4356
|
|
|
4357
|
-
**Consult-before-send gate.** Injection (above) puts the owner's active rules in front of every channel turn, but the growing layer-2 `Preference` set is read on demand with `profile-read`, a per-turn judgement the agent can skip, the miss that dropped a customer signature on a delivered document. `hooks/preference-consult-gate.sh` (admin plugin) is the deliverable-boundary enforcement: a PreToolUse gate on customer-facing document deliverables (`browser-pdf-save`/`SendUserFile` to `memory/users/<phone>/documents/`, and email/Outlook sends carrying attachments) that blocks (exit 2) when no `profile-read` ran after the last user message in the transcript. It fires on documents only, never on casual replies. **Observability:** `[preference-gate] op=allow tool=<name> consulted=true` on an allowed document deliverable, `op=bypass tool=<name> detail=no profile-read this turn` on a block; a stream of `op=bypass` is the un-consulted-send signature. The advisory companion `hooks/preference-consult-directive.sh` injects the two-layer architecture reminder every turn (`[pref-wrapper] op=inject`). The placement half, promoting finished deliverables out of `output/` scratch, is counted by the `data-manager` reconcile audit (`scratch-refs`, `stranded`); making that audit run on a standing periodic cadence is a filed follow-up.
|
|
4357
|
+
**Consult-before-send gate.** Injection (above) puts the owner's active rules in front of every channel turn, but the growing layer-2 `Preference` set is read on demand with `profile-read`, a per-turn judgement the agent can skip, the miss that dropped a customer signature on a delivered document. `hooks/preference-consult-gate.sh` (admin plugin) is the deliverable-boundary enforcement: a PreToolUse gate on customer-facing document deliverables (`browser-pdf-save`/`SendUserFile` to `memory/users/<phone>/documents/`, and email/Outlook sends carrying attachments) that blocks (exit 2) when no `profile-read` ran after the last user message in the transcript. It fires on documents only, never on casual replies. **Observability:** `[preference-gate] op=allow tool=<name> consulted=true` on an allowed document deliverable, `op=bypass tool=<name> detail=no profile-read this turn` on a block; a stream of `op=bypass` is the un-consulted-send signature. The advisory companion `hooks/preference-consult-directive.sh` injects the two-layer architecture reminder every turn (`[pref-wrapper] op=inject`). The placement half, promoting finished deliverables out of `output/` scratch, is counted by the `data-manager` reconcile audit (`scratch-refs`, `stranded`); making that audit run on a standing periodic cadence is a filed follow-up. The inbound mirror is the `uploads/` intake inbox: an uploaded file lands at `uploads/<attachmentId>/` and is promoted to its canonical entity bucket when its graph node is created, so a persisted node reference resolving into `uploads/` is intake drift, counted by the same reconcile audit as `stranded-intake`. Unlike `output/`, `uploads/` is never rebuilt by a tool, so the `data-manager` may promote a file out of it. Beyond placement and intake, the same audit counts intra-folder sprawl inside each operator-data entity folder from disk structure alone: superseded version copies (`<base>.ext` and `<base>-vN.ext` are one deliverable, all but the newest counted `versioned`), format twins (a source `.html`/`.md` render kept beside its delivered `.pdf` of the same basename, counted `format-twins`), and subfolders nested under `projects/<name>/` or `contacts/<name>/` that the flat rule forbids (counted `stray-subdir`). These are read-only counts; removal or flattening happens only on a `data-manager` stewardship dispatch, each paired with a `database-operator` reference update. The reconcile output contract is `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R versioned=S format-twins=T stray-subdir=U`.
|
|
4358
4358
|
|
|
4359
4359
|
---
|
|
4360
4360
|
|
|
@@ -9,6 +9,13 @@ Invoked by the admin agent directly.
|
|
|
9
9
|
|
|
10
10
|
This is the platform's release timeline, newest first. Each entry shows the date it shipped and the version it shipped in, so you can tell the operator how current their install is. To compare, read the installed version from `capabilities-here` and match it against the versions below. Keep answers high level and in plain English; this is a summary, not a full commit log.
|
|
11
11
|
|
|
12
|
+
## 2026-07-25 (0.1.502)
|
|
13
|
+
|
|
14
|
+
- Uploading a file from the phone or desktop app now shows as a proper thumbnail in chat, not a raw file path.
|
|
15
|
+
- Switching accounts now shows a loading screen and lands you on the dashboard instead of a blank page.
|
|
16
|
+
- Uploaded files are automatically filed into the right folder instead of sitting in a temporary holding area.
|
|
17
|
+
- Searching your files is more reliable and no longer times out on larger accounts.
|
|
18
|
+
|
|
12
19
|
## 2026-07-21 (0.1.482)
|
|
13
20
|
|
|
14
21
|
- WhatsApp now runs a separate connection for each client account, so one client's messages never mix with another's.
|
|
@@ -408,7 +408,7 @@ Standing rules the operator gives over a channel are `Preference` nodes. Two mec
|
|
|
408
408
|
|
|
409
409
|
**Observability.** `[preference-write] op=reconcile … mode=<reinforce|update|contradict|new> similarity=…` — a stream of `mode=new` for subjects that already exist is the duplicate-minting signature. `[preference-inject] op=inject channel=<wa|tg|web> injected=<N> owner=<8> source=<owner|no-owner|owner-error|fetch-error>` — injection selects only the account owner's admin preferences, so `source=owner injected=0` is a genuinely empty owner, `source=no-owner` is an account with no seeded owner (injects nothing, a missed owner seeding), and `injected=0 source=owner` on an account whose owner holds rules is the write-only regression re-appearing. `[preference-inject] op=reconcile accountId=… stored=… injected=…` — the standing reconciliation audit (claude-session-manager, 5-minute tick) flags any account whose stored active count diverges from what injection surfaces; injection now surfaces every stored active preference verbatim, so `stored == injected` is the healthy signal and any gap is a dropped-row regression (a reintroduced cap, filter, or truncation). A clean pass logs `op=reconcile drifted=0`, the no-event detector.
|
|
410
410
|
|
|
411
|
-
**Consult-before-send gate.** Injection (above) puts the owner's active rules in front of every channel turn, but the growing layer-2 `Preference` set is read on demand with `profile-read`, a per-turn judgement the agent can skip, the miss that dropped a customer signature on a delivered document. `hooks/preference-consult-gate.sh` (admin plugin) is the deliverable-boundary enforcement: a PreToolUse gate on customer-facing document deliverables (`browser-pdf-save`/`SendUserFile` to `memory/users/<phone>/documents/`, and email/Outlook sends carrying attachments) that blocks (exit 2) when no `profile-read` ran after the last user message in the transcript. It fires on documents only, never on casual replies. **Observability:** `[preference-gate] op=allow tool=<name> consulted=true` on an allowed document deliverable, `op=bypass tool=<name> detail=no profile-read this turn` on a block; a stream of `op=bypass` is the un-consulted-send signature. The advisory companion `hooks/preference-consult-directive.sh` injects the two-layer architecture reminder every turn (`[pref-wrapper] op=inject`). The placement half, promoting finished deliverables out of `output/` scratch, is counted by the `data-manager` reconcile audit (`scratch-refs`, `stranded`); making that audit run on a standing periodic cadence is a filed follow-up.
|
|
411
|
+
**Consult-before-send gate.** Injection (above) puts the owner's active rules in front of every channel turn, but the growing layer-2 `Preference` set is read on demand with `profile-read`, a per-turn judgement the agent can skip, the miss that dropped a customer signature on a delivered document. `hooks/preference-consult-gate.sh` (admin plugin) is the deliverable-boundary enforcement: a PreToolUse gate on customer-facing document deliverables (`browser-pdf-save`/`SendUserFile` to `memory/users/<phone>/documents/`, and email/Outlook sends carrying attachments) that blocks (exit 2) when no `profile-read` ran after the last user message in the transcript. It fires on documents only, never on casual replies. **Observability:** `[preference-gate] op=allow tool=<name> consulted=true` on an allowed document deliverable, `op=bypass tool=<name> detail=no profile-read this turn` on a block; a stream of `op=bypass` is the un-consulted-send signature. The advisory companion `hooks/preference-consult-directive.sh` injects the two-layer architecture reminder every turn (`[pref-wrapper] op=inject`). The placement half, promoting finished deliverables out of `output/` scratch, is counted by the `data-manager` reconcile audit (`scratch-refs`, `stranded`); making that audit run on a standing periodic cadence is a filed follow-up. The inbound mirror is the `uploads/` intake inbox: an uploaded file lands at `uploads/<attachmentId>/` and is promoted to its canonical entity bucket when its graph node is created, so a persisted node reference resolving into `uploads/` is intake drift, counted by the same reconcile audit as `stranded-intake`. Unlike `output/`, `uploads/` is never rebuilt by a tool, so the `data-manager` may promote a file out of it. Beyond placement and intake, the same audit counts intra-folder sprawl inside each operator-data entity folder from disk structure alone: superseded version copies (`<base>.ext` and `<base>-vN.ext` are one deliverable, all but the newest counted `versioned`), format twins (a source `.html`/`.md` render kept beside its delivered `.pdf` of the same basename, counted `format-twins`), and subfolders nested under `projects/<name>/` or `contacts/<name>/` that the flat rule forbids (counted `stray-subdir`). These are read-only counts; removal or flattening happens only on a `data-manager` stewardship dispatch, each paired with a `database-operator` reference update. The reconcile output contract is `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R versioned=S format-twins=T stray-subdir=U`.
|
|
412
412
|
|
|
413
413
|
---
|
|
414
414
|
|
|
@@ -26,6 +26,32 @@ the client data portal, and case-sensitive matching. The write guard blocks a ba
|
|
|
26
26
|
name as you create it, and the standing reconcile counts any that predate the
|
|
27
27
|
rule. Renaming an existing bad name goes through the `data-manager` specialist.
|
|
28
28
|
|
|
29
|
+
## Intra-folder hygiene
|
|
30
|
+
|
|
31
|
+
The `projects/<name>/` and `contacts/<name>/` entity folders hold one current
|
|
32
|
+
copy of each deliverable, in one canonical format, with no subtree. Three rules
|
|
33
|
+
keep them that way; the standing reconcile counts any that predate them, and
|
|
34
|
+
`data-manager` clears them on a stewardship dispatch. (`documents/` is exempt: it
|
|
35
|
+
may hold one document-folder deep per the buckets above, so these rules do not
|
|
36
|
+
apply there.)
|
|
37
|
+
|
|
38
|
+
- **Current version only.** `<base>.ext` and `<base>-vN.ext` (for example
|
|
39
|
+
`charlotte-deck.pdf` and `charlotte-deck-v2.pdf` through
|
|
40
|
+
`charlotte-deck-v6.pdf`) are versions of one deliverable, not separate files.
|
|
41
|
+
Keep the highest-numbered version (the unsuffixed base is the original, so any
|
|
42
|
+
`-vN` supersedes it); the superseded copies are removed through `data-manager`.
|
|
43
|
+
- **One canonical format.** A delivered `.pdf` and its source render sharing the
|
|
44
|
+
same basename (`charlotte-deck.html` beside `charlotte-deck.pdf`,
|
|
45
|
+
`invoice-rbt-2026-005.html` beside `invoice-rbt-2026-005.pdf`) are one
|
|
46
|
+
deliverable in two formats. The pdf is the deliverable; the `.html` or `.md`
|
|
47
|
+
render that produced it is not a second one and is removed through
|
|
48
|
+
`data-manager`.
|
|
49
|
+
- **No subfolder.** No folder nests under `projects/<name>/` or
|
|
50
|
+
`contacts/<name>/`; files live directly inside the entity folder. This is the
|
|
51
|
+
flat rule from the buckets above, restated as a standing invariant: the write
|
|
52
|
+
guard blocks the depth as you create it, and the reconcile counts any subtree
|
|
53
|
+
that predates the guard or was created off-path.
|
|
54
|
+
|
|
29
55
|
## Tool-owned (off-limits — never reorganise)
|
|
30
56
|
|
|
31
57
|
Finished deliverables must be promoted out of `output/` into `documents/` or
|
|
@@ -33,8 +59,17 @@ Finished deliverables must be promoted out of `output/` into `documents/` or
|
|
|
33
59
|
last resort, and a graph reference must never point into it (the next tool write
|
|
34
60
|
rebuilds the tree and the reference dangles).
|
|
35
61
|
|
|
62
|
+
`uploads/` is a temporary intake inbox, not rebuilt scratch. A file lands at
|
|
63
|
+
`uploads/<attachmentId>/` on upload and is promoted to its canonical entity
|
|
64
|
+
bucket when its graph node is created: a Person or Organization file to
|
|
65
|
+
`contacts/<name>/`, a Project file to `projects/<name>/`, anything else to
|
|
66
|
+
`documents/`. A persisted graph reference must never point into `uploads/`.
|
|
67
|
+
Unlike `output/`, each upload writes its own `uploads/<attachmentId>/` dir and no
|
|
68
|
+
tool walks or rebuilds the subtree, so promoting a file out of it through the
|
|
69
|
+
`data-manager` specialist is safe.
|
|
70
|
+
|
|
36
71
|
The internal structure of these is owned by the writing tool and is recreated on
|
|
37
|
-
the next write: `url-get/`, `output/`, `generated/`, `extracted/`,
|
|
72
|
+
the next write: `url-get/`, `output/`, `generated/`, `extracted/`,
|
|
38
73
|
any published/served tree (`sites/`, `public/`), `agents/`, `specialists/`, and
|
|
39
74
|
platform-internal areas (`cache/`, `secrets/`, `state/`, `logs/`, `tmp/`).
|
|
40
75
|
`.quarantine/` is a historical store. An earlier version of the schema reconcile
|
|
@@ -14,6 +14,8 @@ You are the steward of this account's data directory. Admin dispatches you throu
|
|
|
14
14
|
- The account data directory is organised consistently with the graph ontology. Before the first move of a session, Read `platform/plugins/memory/references/schema-base.md`; when `brand.json#vertical` is set, also Read `platform/plugins/memory/references/schema-<vertical>.md`. Directory structure and file placement should make sense to someone navigating by the graph: files that belong to a Project, Person, or document node live where the node's references say they live.
|
|
15
15
|
- Every operator file is reachable from a graph node, and every graph file-reference resolves to a real path. `memory-search` is how you resolve which nodes reference a file — search for the filename and the path before deciding anything about it.
|
|
16
16
|
- A file is never moved without the referencing nodes being updated in the same pass. Moves and reference updates are paired operations: for each move, dispatch `database-operator` via the Task tool with a brief naming the node (elementId from your `memory-search`), the property holding the old path, and the new path. You have no graph-write tools by design — every graph mutation flows through database-operator.
|
|
17
|
+
- A file in the `uploads/` intake inbox whose graph node exists is promoted to its canonical bucket (Person or Organization to `contacts/<name>/`, Project to `projects/<name>/`, else `documents/`), paired with a `database-operator` `sourcePath` update in the same pass, exactly as any other move. `uploads/` is a temporary landing area, not a tool-owned tree, so moving a file out of it is not a reorganisation of a system-convention directory.
|
|
18
|
+
- Superseded versions and redundant format twins are removed, and a subfolder nested under `projects/<name>/` or `contacts/<name>/` is flattened or re-filed, when a stewardship brief asks for it. Each removal or move pairs with a `database-operator` reference update in the same pass, exactly as any other move: the surviving current render keeps the node reference, and a removed file's node is repointed or its reference dropped. Removal is destructive, so it happens only on an explicit stewardship dispatch, never in the read-only reconcile audit.
|
|
17
19
|
|
|
18
20
|
## Off-limits: system-convention directories
|
|
19
21
|
|
|
@@ -21,13 +23,13 @@ Directories whose layout is owned by tools are not yours to reorganise — a too
|
|
|
21
23
|
|
|
22
24
|
## The reconcile audit brief
|
|
23
25
|
|
|
24
|
-
When admin's brief names a reconcile audit, the pass is read-only: walk the operator-file areas of the account directory, resolve each file against the graph via `memory-search`, and count (a) files unreachable from any graph node, (b) graph file-references that do not resolve to a real path, (c) graph file-references that resolve into a tool-owned scratch dir (`output/`, `generated/`, `extracted/`, `url-get/`), which the next tool write rebuilds so the reference is fragile by construction,
|
|
26
|
+
When admin's brief names a reconcile audit, the pass is read-only: walk the operator-file areas of the account directory, resolve each file against the graph via `memory-search`, and count (a) files unreachable from any graph node, (b) graph file-references that do not resolve to a real path, (c) graph file-references that resolve into a tool-owned scratch dir (`output/`, `generated/`, `extracted/`, `url-get/`), which the next tool write rebuilds so the reference is fragile by construction, (d) deliverables a node references that resolve only under a scratch dir and were never promoted to `documents/` or `projects/`, and (e) graph file-references that resolve into the `uploads/` intake inbox, which is a temporary landing area a file should have been promoted out of when its node was created. The walk now includes `uploads/`; a file under `uploads/` that no node references counts under (a) unreachable. Then, per operator-data entity folder (`projects/<name>/`, `contacts/<name>/`), count three intra-folder drifts from disk structure alone, no graph resolution needed: (f) files in a version group, where `<base>.ext` and `<base>-vN.ext` share a basename stem and extension and all but the newest are superseded, counting every superseded copy as `versioned`; (g) format twins, a source-render file (`.html`, `.md`) whose delivered `.pdf` twin of the same basename sits in the same folder, counting each such render as `format-twins`; (h) stray subfolders nested under an entity folder, which the flat rule forbids, counting each subfolder as `stray-subdir`. Move nothing, dispatch nothing. The audit exists so a rising count is visible before anyone asks for a cleanup.
|
|
25
27
|
|
|
26
28
|
When the vertical's `schema-<vertical>.md` declares a **published / served tree** with a Filesystem ↔ graph section (e.g. the per-listing site target with a URL ↔ path rule and an artefact → graph-reference table), the audit also walks that tree. The graph references it by hosted URL, not local path, so resolution runs through the section's URL ↔ path rule: for each served file, derive its hosted URL and check that some node references it; for each node URL **that matches the section's hosted-URL prefix**, derive its local path and check the file exists. Count served files matching no node reference in `unreachable` and prefix-matching node URLs resolving to no served file in `broken-refs`. Node URLs the rule cannot resolve — externally-hosted URLs (a CDN image, a third-party portal link) carry no served-tree prefix — are outside this audit and are never counted as broken. Honour the section's "served but intentionally unreferenced (tool / collateral)" list — those classes carry no reference by design and are never orphans, the same exclusion you already apply to the `url-get/` cache. This walk is still read-only: the served tree is a publish write target (off-limits to moves, above); the audit only counts drift, it never reorganises.
|
|
27
29
|
|
|
28
30
|
## Output contract
|
|
29
31
|
|
|
30
|
-
End every dispatch with a one-line machine-greppable summary as the last line of your reply. For stewardship work: `moves=N ref-updates=M skipped=<reason|none>`. For the reconcile audit: `unreachable=N broken-refs=M scratch-refs=P stranded=Q`. If a brief is ambiguous about whether a directory is operator data or a system convention, name the ambiguity in your reply instead of guessing.
|
|
32
|
+
End every dispatch with a one-line machine-greppable summary as the last line of your reply. For stewardship work: `moves=N ref-updates=M skipped=<reason|none>`. For the reconcile audit: `unreachable=N broken-refs=M scratch-refs=P stranded=Q stranded-intake=R versioned=S format-twins=T stray-subdir=U`. If a brief is ambiguous about whether a directory is operator data or a system convention, name the ambiguity in your reply instead of guessing.
|
|
31
33
|
|
|
32
34
|
## Review gates
|
|
33
35
|
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
6
|
<title>Activity — Maxy</title>
|
|
7
7
|
<link rel="icon" href="/favicon.ico">
|
|
8
|
-
<script type="module" crossorigin src="/assets/activity-
|
|
8
|
+
<script type="module" crossorigin src="/assets/activity-DZFYDHNA.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/chunk-CCr-iYLO.js">
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-
|
|
11
|
-
<link rel="modulepreload" crossorigin href="/assets/AdminShell-
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/assets/triangle-alert-
|
|
13
|
-
<link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/assets/useSubAccountSwitcher-iQGqNJhI.js">
|
|
11
|
+
<link rel="modulepreload" crossorigin href="/assets/AdminShell-Gq8DU_ig.js">
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/assets/triangle-alert-k8ulav-N.js">
|
|
13
|
+
<link rel="stylesheet" crossorigin href="/assets/useSubAccountSwitcher-fvBunpOC.css">
|
|
14
14
|
<link rel="stylesheet" href="/brand-defaults.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|