Skip to content

Commit 0a2f233

Browse files
claudeos-zhuang
authored andcommitted
fix(spec): regenerate the ADR-0087 manifest + upgrade guide the RC bump left stale
The v17 RC version bump moved PROTOCOL_VERSION to 17.0.0 without re-running gen:spec-changes / gen:upgrade-guide, so spec-changes.json still declared protocolVersion 16.0.0 with no protocol-17 entries while the protocol-17 conversions were already registered and live. check:spec-changes (Check Generated Artifacts) fails on pristine origin/main — reproduced in a detached worktree — and surfaced here only because this PR is the first since the bump to touch a path the job's filter watches (skills/**). Mechanical regeneration, no hand edits: spec-changes.json gains the five protocol-17 conversions and protocolVersion 17.0.0; the upgrade guide gains its generated Protocol 16 → 17 section. All four job steps now pass locally (check:skill-docs, check:spec-changes, check:upgrade-guide, check:authorable-surface). Ships as a spec patch so npm consumers get the corrected manifest. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LXvaYR7TiJBCxYwjn51owH
1 parent bec0f9a commit 0a2f233

3 files changed

Lines changed: 109 additions & 3 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
"@objectstack/spec": patch
3+
---
4+
5+
fix(spec): regenerate the ADR-0087 change manifest the RC version bump left stale
6+
7+
The v17 RC bump moved `PROTOCOL_VERSION` to `17.0.0` but did not re-run
8+
`gen:spec-changes` / `gen:upgrade-guide`, so the published `spec-changes.json`
9+
still declared `protocolVersion: 16.0.0` with no protocol-17 entries — while the
10+
protocol-17 conversions (`execute``target`, `conditionalRequired``requiredWhen`,
11+
`knowledge.topics``sources`, `agent.tools` removal, sharing `full``edit`) were
12+
already registered and applied at load. Anything projecting the manifest (the
13+
generated upgrade guide, the `spec_changes` MCP tool) reported a 16-era chain on
14+
a 17 protocol.
15+
16+
`check:spec-changes` caught it, but only on the first PR to touch a
17+
generated-artifacts path after the bump — this regenerates both projections and
18+
turns the gate green again. `docs/protocol-upgrade-guide.md` now carries the
19+
Protocol 16 → 17 section.

docs/protocol-upgrade-guide.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
# Metadata protocol upgrade guide
55

6-
Current protocol: **16.0.0** · chain support floor: **protocol 10** · generated from the ADR-0087 registries (`@objectstack/spec` `conversions/` + `migrations/`).
6+
Current protocol: **17.0.0** · chain support floor: **protocol 10** · generated from the ADR-0087 registries (`@objectstack/spec` `conversions/` + `migrations/`).
77

88
## How to upgrade — from any past major
99

@@ -114,6 +114,24 @@ Protocol 16 flipped `DashboardWidgetSchema` to `.strict()` (framework#3251, ADR-
114114
- Why not automatic: The `.strict()` flip turns a previously silently-stripped unknown key into a parse error. There is no mapping target for an arbitrary unknown key — auto-deleting it would be exactly the silent data loss ADR-0078 bans — so each occurrence needs the author to decide: bind a `dataset` and select `dimensions`/`values`, move a renderer setting under `options`, or delete the dead key.
115115
- Done when: `objectstack validate` passes with no unknown-key parse errors on dashboard widgets.
116116

117+
## Protocol 16 → 17
118+
119+
Protocol 17 removes the last three deprecated authorable aliases: action `execute` (use `target`), field `conditionalRequired` (use `requiredWhen`), and agent `knowledge.topics` (use `knowledge.sources`). Each was already lowered into its canonical key at parse time and dropped from the parsed output, so no runtime behaviour changes — only the authorable surface shrinks to one spelling per slot. All three are pure key renames with unchanged values and replay losslessly; the schemas reject the removed spellings with a fix-it error naming the replacement.
120+
121+
It also removes the sharing-rule access level `full` (#3865): declared as "Full Access (Transfer, Share, Delete)" but never enforced as anything but `edit` — both gates matched `edit`/`full` alike, so Setup promised admins a delete grant it never issued (ADR-0078). Unlike the OWD `sharingModel: 'full'` alias retired at step 13, this one HAS a lossless target precisely because it was inert — old and new shapes are behaviourally identical — so it converts mechanically and leaves no semantic residue. It is the one protocol-17 conversion that keeps a load-path acceptance window: it had no prior deprecation, and a removed enum value cannot carry the fix-it error the three key renames tombstone theirs with.
122+
123+
Finally it removes agent `tools` (#3894): the legacy inline `{type,name,description}[]` fallback, which the runtime resolved against the FULL tool registry with no surface check — the one seam that broke ADR-0064's "an agent reaches exactly its surface-compatible skills' tools, nothing falls through to the global registry". Unlike the renames above this has NO lossless target: each entry has to become a reference inside a skill, which is a human decision about which skill. The conversion therefore drops the dead key (the runtime stopped reading it in cloud#910, so it already contributes nothing) and emits a notice per agent so the author knows where capability must be re-declared; the schema tombstones the key with a fix-it error naming `skills`.
124+
125+
### Mechanical (applied for you)
126+
127+
| Conversion | Surface | Change | Load window |
128+
|---|---|---|---|
129+
| `action-execute-to-target` | `action.execute` | action key 'execute' → 'target' (the deprecated handler alias, #3713) | retired — `migrate meta` only |
130+
| `field-conditionalRequired-to-requiredWhen` | `field.conditionalRequired` | field key 'conditionalRequired' → 'requiredWhen' (the deprecated predicate alias, #3754) | retired — `migrate meta` only |
131+
| `agent-knowledge-topics-to-sources` | `agent.knowledge.topics` | agent knowledge key 'topics' → 'sources' (the deprecated RAG-source alias, #1891) | retired — `migrate meta` only |
132+
| `agent-tools-to-skills` | `agent.tools` | agent key 'tools' removed — declare capability in a skill (ADR-0064, #3894) | retired — `migrate meta` only |
133+
| `sharing-rule-access-level-full-to-edit` | `sharingRule.accessLevel` | sharing-rule accessLevel 'full' → 'edit' (#3865`full` never granted more than `edit`) | live — protocol 17 loader accepts the old shape |
134+
117135
---
118136

119137
*Machine-readable equivalents: `spec-changes.json` (shipped in `@objectstack/spec` and attached to each GitHub Release) and the structured output of `objectstack migrate meta --json`.*

packages/spec/spec-changes.json

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"$comment": "GENERATED (ADR-0087 D4) — do not edit. Regenerate with: pnpm --filter @objectstack/spec gen:spec-changes. A projection of the D2 conversion table + D3 migration chain; the upgrade guide and the MCP spec_changes tool derive from this same data.",
3-
"protocolVersion": "16.0.0",
3+
"protocolVersion": "17.0.0",
44
"supportFloor": 10,
55
"migrateCommand": "objectstack migrate meta --from <N> (N >= 10)",
66
"aggregate": {
77
"from": 10,
8-
"to": 16,
8+
"to": 17,
99
"added": [],
1010
"converted": [
1111
{
@@ -67,6 +67,36 @@
6767
"to": "page component key 'visibility' → 'visibleWhen' (ADR-0089)",
6868
"conversionId": "page-component-visibility-to-visibleWhen",
6969
"toMajor": 15
70+
},
71+
{
72+
"surface": "action.execute",
73+
"to": "action key 'execute' → 'target' (the deprecated handler alias, #3713)",
74+
"conversionId": "action-execute-to-target",
75+
"toMajor": 17
76+
},
77+
{
78+
"surface": "field.conditionalRequired",
79+
"to": "field key 'conditionalRequired' → 'requiredWhen' (the deprecated predicate alias, #3754)",
80+
"conversionId": "field-conditionalRequired-to-requiredWhen",
81+
"toMajor": 17
82+
},
83+
{
84+
"surface": "agent.knowledge.topics",
85+
"to": "agent knowledge key 'topics' → 'sources' (the deprecated RAG-source alias, #1891)",
86+
"conversionId": "agent-knowledge-topics-to-sources",
87+
"toMajor": 17
88+
},
89+
{
90+
"surface": "agent.tools",
91+
"to": "agent key 'tools' removed — declare capability in a skill (ADR-0064, #3894)",
92+
"conversionId": "agent-tools-to-skills",
93+
"toMajor": 17
94+
},
95+
{
96+
"surface": "sharingRule.accessLevel",
97+
"to": "sharing-rule accessLevel 'full' → 'edit' (#3865 — `full` never granted more than `edit`)",
98+
"conversionId": "sharing-rule-access-level-full-to-edit",
99+
"toMajor": 17
70100
}
71101
],
72102
"migrated": [
@@ -330,6 +360,45 @@
330360
}
331361
],
332362
"removed": []
363+
},
364+
{
365+
"from": 16,
366+
"to": 17,
367+
"added": [],
368+
"converted": [
369+
{
370+
"surface": "action.execute",
371+
"to": "action key 'execute' → 'target' (the deprecated handler alias, #3713)",
372+
"conversionId": "action-execute-to-target",
373+
"toMajor": 17
374+
},
375+
{
376+
"surface": "field.conditionalRequired",
377+
"to": "field key 'conditionalRequired' → 'requiredWhen' (the deprecated predicate alias, #3754)",
378+
"conversionId": "field-conditionalRequired-to-requiredWhen",
379+
"toMajor": 17
380+
},
381+
{
382+
"surface": "agent.knowledge.topics",
383+
"to": "agent knowledge key 'topics' → 'sources' (the deprecated RAG-source alias, #1891)",
384+
"conversionId": "agent-knowledge-topics-to-sources",
385+
"toMajor": 17
386+
},
387+
{
388+
"surface": "agent.tools",
389+
"to": "agent key 'tools' removed — declare capability in a skill (ADR-0064, #3894)",
390+
"conversionId": "agent-tools-to-skills",
391+
"toMajor": 17
392+
},
393+
{
394+
"surface": "sharingRule.accessLevel",
395+
"to": "sharing-rule accessLevel 'full' → 'edit' (#3865 — `full` never granted more than `edit`)",
396+
"conversionId": "sharing-rule-access-level-full-to-edit",
397+
"toMajor": 17
398+
}
399+
],
400+
"migrated": [],
401+
"removed": []
333402
}
334403
]
335404
}

0 commit comments

Comments
 (0)