@sporhq/spor 0.21.0 → 0.22.0
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/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/API.md +15 -0
- package/GRAPH.md +10 -0
- package/lib/seed/schema-person.md +24 -1
- package/package.json +1 -1
- package/skills/onboard/SKILL.md +27 -4
- package/skills/spor/references/concepts.md +3 -2
- package/skills/triage/SKILL.md +11 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "spor",
|
|
3
3
|
"displayName": "Spor Context Compiler",
|
|
4
4
|
"description": "Maintains a typed, versioned knowledge graph and compiles compact briefings from it: session-start injection, per-prompt relevance digests, capture at discovery, end-of-session distillation, decision queue.",
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.22.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "losthammer"
|
|
8
8
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Maintains a typed, versioned knowledge graph and compiles compact briefings from it: session-start injection, per-prompt relevance digests, capture at discovery, end-of-session distillation, decision queue.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Spor",
|
package/API.md
CHANGED
|
@@ -69,6 +69,21 @@ neighbor → neighbor); `render_lens` lineage lenses trace why a node exists,
|
|
|
69
69
|
and `render_lens` with no `lens_id` returns the lens catalog (the discovery
|
|
70
70
|
step before rendering).
|
|
71
71
|
|
|
72
|
+
**Per-viewer language register** (task-spor-viewer-register-adaptation): when
|
|
73
|
+
the authenticated viewer's person node carries a free-text `register:` field
|
|
74
|
+
(GRAPH.md "person" — role + preferred language style), the server renders it
|
|
75
|
+
on two channels so the host's model adapts how it explains graph content to
|
|
76
|
+
that user. (1) The initialize `instructions` gain a trailing **`AUDIENCE`**
|
|
77
|
+
section quoting the field; (2) the conversational read tools — `query_graph`,
|
|
78
|
+
`get_node`, `explore_graph`, `show_queue` — prepend one line to their TEXT
|
|
79
|
+
content: `Audience note — how to communicate with this user: <register>`.
|
|
80
|
+
Both channels because host support for instructions is uneven. The preamble
|
|
81
|
+
is presentation-only: `structuredContent` is never touched, `isError` results
|
|
82
|
+
are exempt, and content is never filtered or reordered by it. The field is
|
|
83
|
+
capped at 500 chars on render; agent-scoped identities (dispatch tokens) get
|
|
84
|
+
neither channel — the register describes the human reader. Absent the field,
|
|
85
|
+
both channels are byte-identical to before.
|
|
86
|
+
|
|
72
87
|
### `query_graph`
|
|
73
88
|
|
|
74
89
|
The compiler over the wire. Input:
|
package/GRAPH.md
CHANGED
|
@@ -640,6 +640,8 @@ email: losthammer@gmail.com
|
|
|
640
640
|
github: losthammer
|
|
641
641
|
roles: [reviewer, maintainer]
|
|
642
642
|
queue_mute: [some-noisy-project, task-noisy-job@2026-07-01]
|
|
643
|
+
register: Non-technical founder. Plain everyday language, no graph jargon;
|
|
644
|
+
use node titles, never raw ids. Analogies over precision.
|
|
643
645
|
date: 2026-06-10
|
|
644
646
|
edges:
|
|
645
647
|
- {type: stewards, to: norm-cc-registry-is-contract}
|
|
@@ -653,6 +655,14 @@ edges:
|
|
|
653
655
|
(issue-cc-identity-email-mutable-primary-key). The token's `{name, email}`
|
|
654
656
|
attribution is read from the bound node, never from a caller parameter
|
|
655
657
|
(dec-viewer-token-binding, dec-cc-attribution-from-token).
|
|
658
|
+
- **`register` is the language-register field** (free-text folded scalar): the
|
|
659
|
+
reader's role and preferred language style. Viewer-facing surfaces (the
|
|
660
|
+
server's MCP instructions block and the conversational read tools' `Audience
|
|
661
|
+
note` preamble) render it verbatim so the model adapts how it talks about
|
|
662
|
+
graph content to this person — a non-technical user gets plain language
|
|
663
|
+
instead of node-type jargon (task-spor-viewer-register-adaptation).
|
|
664
|
+
Presentation only: it never changes what is returned. Settable from chat by
|
|
665
|
+
updating your own person node.
|
|
656
666
|
- **`stewards` edges are the routing key.** A `person → node` `stewards` edge
|
|
657
667
|
declares ownership of an area, spec, or norm. When a question can't be
|
|
658
668
|
answered from the graph and is filed (`ask_question` / `POST /v1/questions`),
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: schema-person
|
|
3
3
|
type: schema
|
|
4
4
|
kind: node-schema
|
|
5
|
-
schema_version: 2026.
|
|
5
|
+
schema_version: 2026.07.14.1
|
|
6
6
|
title: Seed schema for person nodes
|
|
7
7
|
summary: Node schema for the person type — a member of the org, with a mutable display name plus the identity anchor for $viewer binding and Tier-2 question routing. Seed-pack default; a graph-resident schema node for this type overrides it.
|
|
8
8
|
date: 2026-06-10
|
|
@@ -41,6 +41,25 @@ node may reach a resolving/done state. Declarative data only — absent it, a
|
|
|
41
41
|
person holds no roles and the field has no effect, so this register is purely
|
|
42
42
|
additive (existing person nodes are unchanged).
|
|
43
43
|
|
|
44
|
+
`register` (2026.07.14.1) is the person node's language-register field (folded
|
|
45
|
+
scalar, free-text prose): how to communicate with this user — their role and
|
|
46
|
+
preferred language style, e.g. `register: Non-technical founder. Plain
|
|
47
|
+
everyday language, no graph jargon; use node titles, never raw ids.` Consumers
|
|
48
|
+
that render graph content *to* this person (the server's MCP instructions
|
|
49
|
+
block and conversational tool-result preambles; API.md §2) surface it verbatim
|
|
50
|
+
so the model adapts its language to the reader
|
|
51
|
+
(task-spor-viewer-register-adaptation). Free text on purpose — the model
|
|
52
|
+
follows prose directly, so no enum→instruction translation table exists to
|
|
53
|
+
drift. When setting it on a user's behalf, don't transcribe a vague
|
|
54
|
+
preference ("keep it simple") — interview briefly, compose 2–4 directive
|
|
55
|
+
sentences a model can act on (vocabulary level, node titles vs raw ids,
|
|
56
|
+
analogies vs precision, detail depth), and confirm the draft with the user
|
|
57
|
+
before writing. Per-viewer presentation only, read via the same `$viewer` binding as
|
|
58
|
+
`queue_mute`; it never changes what content is returned, only how the
|
|
59
|
+
assistant is told to talk about it. Declarative data only — absent it, nothing
|
|
60
|
+
is injected and the field has no effect, so this register is purely additive
|
|
61
|
+
(existing person nodes are unchanged).
|
|
62
|
+
|
|
44
63
|
`github` (2026.06.21.1) is the person node's GitHub-handle register (flat inline
|
|
45
64
|
scalar): `github: octocat`. It is the login→person key the Spor server's GitHub
|
|
46
65
|
review reflection maps by: when a GitHub review or merge is reflected into the
|
|
@@ -77,6 +96,10 @@ register is purely additive (existing person nodes are unchanged).
|
|
|
77
96
|
"kind": "inline-list",
|
|
78
97
|
"description": "role-list register consumed by policy quorum gates"
|
|
79
98
|
},
|
|
99
|
+
"register": {
|
|
100
|
+
"kind": "scalar",
|
|
101
|
+
"description": "free-text language register — the reader's role and preferred language style, rendered to the model on viewer-facing surfaces"
|
|
102
|
+
},
|
|
80
103
|
"github": {
|
|
81
104
|
"kind": "scalar",
|
|
82
105
|
"aliases": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sporhq/spor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "Spor — a shared memory substrate for teams and agents. Decisions, their reasons, and the traces they leave. Knowledge-graph context compiler: session-start briefings, per-prompt digests, capture at discovery, end-of-session distillation, decision queue.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Anthony Allen",
|
package/skills/onboard/SKILL.md
CHANGED
|
@@ -66,20 +66,43 @@ attribute to you and your queue and question-routing work.
|
|
|
66
66
|
hand it over; the user then re-runs step 1 with it. Don't paper over it — silent
|
|
67
67
|
identity degradation is exactly the failure this check exists to catch
|
|
68
68
|
(issue-cc-onboarding-email-mismatch-silent-degradation).
|
|
69
|
-
4. **
|
|
69
|
+
4. **Ask how assistants should talk to them — the `register` field.** First
|
|
70
|
+
check `spor get <person-id>` — if the node already carries a `register:`,
|
|
71
|
+
this step is done (mention it exists and move on; don't re-interview a
|
|
72
|
+
returning user). Otherwise interview briefly, then **draft the field
|
|
73
|
+
yourself — never transcribe the user's first answer**. People
|
|
74
|
+
under-specify this in the moment ("just keep it simple" encodes nothing a
|
|
75
|
+
model can act on), so extract the substance: what's their role, how
|
|
76
|
+
technical are they, and what does a useful explanation look like to them —
|
|
77
|
+
asking for an example of an explanation they liked or hated works well.
|
|
78
|
+
From that, compose 2–4 directive sentences a model can follow mechanically
|
|
79
|
+
(vocabulary level, node titles vs raw ids, analogies vs precision, detail
|
|
80
|
+
depth — e.g. `register: Non-technical founder. Plain everyday language, no
|
|
81
|
+
graph jargon; use node titles, never raw ids. Analogies over precision.`),
|
|
82
|
+
read the draft back for approval, and write the approved version to their
|
|
83
|
+
person node (GRAPH.md "person"): `spor get <person-id> --json` for the
|
|
84
|
+
revision, add the field, then
|
|
85
|
+
`spor put-node - --if-exists update --revision <sha>`. The server renders it
|
|
86
|
+
to every graph-reading assistant (MCP instructions + an Audience note on
|
|
87
|
+
reads), so a non-technical user gets answers they can actually use — for
|
|
88
|
+
them this is the highest-value step here
|
|
89
|
+
(task-spor-viewer-register-adaptation). Presentation only, editable any time
|
|
90
|
+
by updating their person node; a technical user happy with the default
|
|
91
|
+
needs no field — skip without ceremony.
|
|
92
|
+
5. **Enable this repo.** `spor enable` writes `.spor.json {enabled: true}` so the
|
|
70
93
|
plugin actually runs here — without a marker every hook no-ops (the opt-in
|
|
71
94
|
default), even in remote mode. Commit the file to share the setting. If the
|
|
72
95
|
inferred project slug is wrong, `spor link <slug>` writes a `.spor` marker.
|
|
73
|
-
|
|
96
|
+
6. **(Optional) a dispatch identity**, if the user will run background agents.
|
|
74
97
|
Two explicit steps: `spor agent create <label>` writes the agent node owned by
|
|
75
98
|
your person, then `spor agent use <agent-id>` makes it **this machine's**
|
|
76
99
|
default — that's what turns on session-start capability auto-publish and the
|
|
77
100
|
liveness heartbeat. Creating does not activate; both are needed. Use the full
|
|
78
101
|
`agent-<slug>` id from `spor agent list`, not the bare label.
|
|
79
|
-
|
|
102
|
+
7. **State the data reality correctly.** In remote mode your captures and
|
|
80
103
|
distilled nodes land in the **shared team graph on the server** — visible to
|
|
81
104
|
teammates and attributed to you. It is *not* local-only.
|
|
82
|
-
|
|
105
|
+
8. **Hand off to populate the repo:** `/spor:backfill` (mine history, group
|
|
83
106
|
repos). Tracker/MCP consent happens there — see step 6 of the local branch,
|
|
84
107
|
which applies equally.
|
|
85
108
|
|
|
@@ -166,8 +166,9 @@ token — the node reads "agent on behalf of person"). Other
|
|
|
166
166
|
type-specific fields exist (`wake:` dormancy date; `commits:` linked git shas;
|
|
167
167
|
`pin:`/`exclude:` on corrections; `slugs:`/`fingerprints:`/`tags:` on repo nodes;
|
|
168
168
|
`applies_to_tags:`/`applies_to_repos:`/`applies_to_projects:` ride-along
|
|
169
|
-
selectors on norms; `roles:`/`queue_mute:` on person nodes
|
|
170
|
-
|
|
169
|
+
selectors on norms; `roles:`/`queue_mute:`/`register:` on person nodes, `register` being the
|
|
170
|
+
free-text "how to talk to this reader" language-style field viewer-facing
|
|
171
|
+
surfaces render verbatim) — see GRAPH.md for the complete list.
|
|
171
172
|
|
|
172
173
|
Validate any local node you write: `spor validate` (or
|
|
173
174
|
`node lib/validate.js`), and fix what it flags.
|
package/skills/triage/SKILL.md
CHANGED
|
@@ -237,6 +237,17 @@ item(s) to spend it on; don't sweep the whole backlog unprompted. Skip an item
|
|
|
237
237
|
that's needs-human only because it's someone's assigned work (`assigned →
|
|
238
238
|
person`) — there is no gap to close there.
|
|
239
239
|
|
|
240
|
+
**Entering this pass, proposing candidates is mandatory — never wait for the
|
|
241
|
+
human to name items** (issue-spor-triage-make-ready-pass-never-triggers: the
|
|
242
|
+
first live run skipped the whole pass because nothing solicited a pick). Pull
|
|
243
|
+
the untriaged and needs-human slices (`spor next --readiness untriaged`,
|
|
244
|
+
`--readiness human`, or the `counts_by_readiness` lead you already have from
|
|
245
|
+
pass 1), present the top ~5 as make-ready candidates — one line each: the item
|
|
246
|
+
and the gap you can already see from its why-line/reasons — and ask which to
|
|
247
|
+
work, recommending the highest-ranked unblockers. Picking stays the human's;
|
|
248
|
+
skipping the proposal is not an option unless both buckets are empty (then say
|
|
249
|
+
so in the outcome).
|
|
250
|
+
|
|
240
251
|
For each chosen item:
|
|
241
252
|
|
|
242
253
|
- **Brief it** — `spor brief <id>` (or `query_graph root_id=<id>`) — pulling
|