@plurnk/plurnk-meta 1.3.11 → 1.4.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/.env.defaults +2 -2
- package/CORPUS.md +28 -9
- package/DIVERGENCES.md +3 -2
- package/DOGFOOD.md +48 -31
- package/PLURNK_PERSONALITY.md +11 -24
- package/README.md +7 -3
- package/SPEC.md +112 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +67 -2
- package/dist/index.js.map +1 -1
- package/docs/log.md +18 -11
- package/docs/questions.md +1 -1
- package/docs/worker.md +28 -6
- package/package.json +13 -2
- package/requirements.md +1 -1
- package/docs/known.md +0 -3
- package/docs/unknown.md +0 -3
package/.env.defaults
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# @plurnk/plurnk-meta — the metaproject layer (membership primitives + teaching corpus).
|
|
2
|
-
# Reader-declares (§operator-config-env-defaults): this package's code reads these knobs.
|
|
2
|
+
# Reader-declares ({§operator-config-env-defaults}): this package's code reads these knobs.
|
|
3
3
|
# PREFIX BEND (owner-approved): the knob keeps its subject-named PLURNK_PLUGINS_ prefix —
|
|
4
4
|
# it gates plugins and that is the honest operator-facing name; one-owner-per-key holds.
|
|
5
5
|
|
|
@@ -15,5 +15,5 @@
|
|
|
15
15
|
PLURNK_PLUGINS_TRUSTED_ONLY=0
|
|
16
16
|
|
|
17
17
|
# Whole-product orientation deadline in seconds. This includes exhaustive semantic
|
|
18
|
-
# preparation of the admitted repository
|
|
18
|
+
# preparation of the workspace's admitted project repository before the model is called.
|
|
19
19
|
PLURNK_ACCEPTANCE_TIMEOUT=3600
|
package/CORPUS.md
CHANGED
|
@@ -1,25 +1,44 @@
|
|
|
1
|
-
# plurnk
|
|
1
|
+
# plurnk teaching corpus
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Authored defaults published by `@plurnk/plurnk-meta` and consumed by
|
|
4
|
+
`@plurnk/plurnk-service`. The membership and ownership boundary is specified at
|
|
5
|
+
{§teaching-corpus}; core owns runtime projection.
|
|
4
6
|
|
|
5
7
|
## Contents
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
| Source | Consumer admission |
|
|
10
|
+
| ------------------------------- | ---------------------------------------------------------------------------- |
|
|
11
|
+
| `PLURNK_PERSONALITY.md` | Read before the first-run seed of user-owned `~/.plurnk/AGENTS.md`. |
|
|
12
|
+
| `requirements.md` | Read for the default compact recap rendered under `## Recap`. |
|
|
13
|
+
| `docs/log.md`, `docs/worker.md` | Read when registered built-in pull docs are materialized. |
|
|
14
|
+
| `docs/questions.md` | Read only when operator questions are enabled, then materialized as a doc. |
|
|
15
|
+
|
|
16
|
+
Core materializes eligible pull docs at `worker://plurnk/docs/<name>.md` and
|
|
17
|
+
exposes them through the turn-0 `FIND(worker://plurnk/docs/**)` catalog. Merely
|
|
18
|
+
placing a file in `docs/` does not register a scheme or make speculative
|
|
19
|
+
teaching current. Every listed source is a required package member; a missing
|
|
20
|
+
or failed read surfaces at the admission boundary rather than silently reducing
|
|
21
|
+
the corpus.
|
|
10
22
|
|
|
11
23
|
## The teaching split
|
|
12
24
|
|
|
13
|
-
**
|
|
25
|
+
**Contracts teach the language; docs teach the world.** The contracts parser and
|
|
26
|
+
`plurnk.md` own operation syntax and model-facing language. Core and capability
|
|
27
|
+
specifications own runtime semantics; this package owns their authored teaching
|
|
28
|
+
projections. Live model evidence tests whether that teaching is legible without
|
|
29
|
+
turning telemetry into unsolicited workflow direction.
|
|
14
30
|
|
|
15
31
|
## Contract
|
|
16
32
|
|
|
17
|
-
plurnk-service resolves these files from
|
|
33
|
+
plurnk-service resolves these files from the installed package through `Paths`
|
|
34
|
+
rather than carrying copies in core. Model-facing teaching changes are verified
|
|
35
|
+
through the composed product gates and tracked against the meta owner in the
|
|
36
|
+
monorepo forge.
|
|
18
37
|
|
|
19
|
-
## Teaching doctrine
|
|
38
|
+
## Teaching doctrine
|
|
20
39
|
|
|
21
40
|
**Canon-voice calibration (owner-ruled 2026-07-06, probe-backed).** Voice tunes to the FLOOR model's minimum-audible threshold, never any tier's max compliance. A footer loud enough to fix the floor OVER-DRIVES strong models (live evidence: Grok Build fanatically FOLDs under a loud budget footer). Soft is safe because the engine makes floor-misses RECOVERABLE (premature-200 -> pending-set 409 -> repair); that coupling is load-bearing — if failures stop being recoverable, recalibrate louder. The footer is pluggable; potato-heavy deployments inject more at their discretion. The one recency-sensitive line is await-before-200 (lean-footer A/B, gemma, n=6: 6/6 reap in the recency footer vs 3/6 cached-canon-only). Retreat trigger: 409-repair LOOPS (not single misses); first line restored is await-before-200.
|
|
22
41
|
|
|
23
|
-
**The requiem acceptance gate.** Teaching changes ship against BEFORE/AFTER corpus deltas (reasoning-token + requiem-recurrence), never hunches. Triage separates legibility debt from
|
|
42
|
+
**The requiem acceptance gate.** Teaching changes ship against BEFORE/AFTER corpus deltas (reasoning-token + requiem-recurrence), never hunches. Triage separates legibility debt from genuine protocol friction. Model-owned context is the product property: deterministic state and reversible OPEN/FOLD tools support the model's judgment without prescribing what to hide. A re-probe against >=0.76.5 is owed (grammar lane).
|
|
24
43
|
|
|
25
44
|
**Example doctrine (Arecibo teaching).** Concrete over placeholder — a live model spawned a worker literally named 'name' from a (worker://name) table cell within a day of shipping; placeholders in reserved-bracket forms are doubly banned. Bare-gesture register per section — op-teaching lines carry the gesture, the mechanism stays the engine's; match the surrounding register. Distribution is load-bearing — clustered examples teach false couplings; rebalance coverage, never add runtime prose. TIME is a distribution axis — dynamics teach as protocol-accurate worked multi-turn traces (the Delegation breath), never prose essays; an inaccurate trace (same-turn READ+200) models the wrong protocol.
|
package/DIVERGENCES.md
CHANGED
|
@@ -16,7 +16,8 @@ especially for smaller models.
|
|
|
16
16
|
|
|
17
17
|
Interoperability:
|
|
18
18
|
|
|
19
|
-
- PLURNK
|
|
19
|
+
- PLURNK hosts current MCP servers through `@plurnk/plurnk-mcp`, exposing
|
|
20
|
+
their tools and resources through the ordinary operation language.
|
|
20
21
|
- Clients use AG-UI.
|
|
21
22
|
- Provider adapters use established model APIs.
|
|
22
23
|
|
|
@@ -35,7 +36,7 @@ MCP, AG-UI, or provider wire protocols.
|
|
|
35
36
|
|
|
36
37
|
## AG-UI management extensions
|
|
37
38
|
|
|
38
|
-
AG-UI defines agent
|
|
39
|
+
AG-UI defines agent Runs but not all workspace-management operations PLURNK
|
|
39
40
|
requires. Management actions therefore use AG-UI's extension fields and custom
|
|
40
41
|
events on the same authenticated endpoint.
|
|
41
42
|
|
package/DOGFOOD.md
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
# Metaproject
|
|
1
|
+
# Metaproject orientation-readiness gate
|
|
2
2
|
|
|
3
|
-
This
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
demo, live-model, and modest-candidate paths are
|
|
8
|
-
debugging loop or
|
|
3
|
+
This opt-in capstone asks a floor model to inspect an assembled open-project
|
|
4
|
+
forest through the outside client and deliver an evidence-bearing orientation
|
|
5
|
+
report. It is intentionally expensive: a fresh campaign semantically prepares
|
|
6
|
+
the complete forest. Execute it only after the focused package, integration,
|
|
7
|
+
demo, live-model, and modest-candidate paths are healthy—not as a routine
|
|
8
|
+
debugging loop or release gate.
|
|
9
9
|
|
|
10
10
|
Invoke it with:
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
|
-
|
|
13
|
+
PLURNK_ACCEPTANCE_PROJECT_ROOT=/path/to/open-project-forest \
|
|
14
|
+
PLURNK_CLIENT_CHECKOUT=/path/to/open-client \
|
|
15
|
+
npm run readiness:metaproject -- --model <alias> --requiem --preserve
|
|
14
16
|
```
|
|
15
17
|
|
|
18
|
+
Both paths are explicit preconditions. The runner never guesses a sibling
|
|
19
|
+
checkout or treats another organization under a shared parent directory as
|
|
20
|
+
part of the open project.
|
|
21
|
+
|
|
16
22
|
This gate does not replace the evidence ladder that qualifies it:
|
|
17
23
|
|
|
18
24
|
1. Deterministic package and integration coverage proves owned contracts.
|
|
@@ -22,56 +28,67 @@ This gate does not replace the evidence ladder that qualifies it:
|
|
|
22
28
|
enough to test seriously.
|
|
23
29
|
4. The separate bench lane runs real third-party agentic benchmarks and preserves
|
|
24
30
|
their digest, reasoning, and requiem evidence.
|
|
25
|
-
5. Only after those layers are healthy does this full-forest
|
|
31
|
+
5. Only after those layers are healthy does this full-forest campaign ask whether
|
|
26
32
|
PLURNK is ready to develop PLURNK itself.
|
|
27
33
|
|
|
28
|
-
The
|
|
34
|
+
The canonical `plurnk-service` checkout owns this gate. Its doctrine lives in
|
|
35
|
+
`plurnk-meta` because the report crosses service, contracts, plugins, the
|
|
36
|
+
outside client, project membership, AG-UI, model routing, persistence, and
|
|
37
|
+
forensic digestion.
|
|
29
38
|
|
|
30
39
|
## Preconditions
|
|
31
40
|
|
|
32
41
|
- A clean canonical `plurnk-service` checkout with its gate green.
|
|
33
|
-
- The outside
|
|
42
|
+
- The explicit outside open-client checkout built from its repository head.
|
|
34
43
|
- Every default-installed optional provider resolvable from the daemon.
|
|
35
|
-
-
|
|
44
|
+
- An explicitly assembled open-project forest with its root `AGENTS.md`; shared
|
|
45
|
+
parent directories containing other organizations are not valid substitutes.
|
|
36
46
|
- One inexpensive capable model alias and, optionally, one local smoke-test alias.
|
|
37
47
|
|
|
38
48
|
Missing preconditions are RED outcomes. The runner never silently skips a phase.
|
|
39
49
|
|
|
40
50
|
## Contract
|
|
41
51
|
|
|
42
|
-
One
|
|
52
|
+
One campaign proves the following through production client and AG-UI surfaces:
|
|
53
|
+
|
|
54
|
+
1. **Candidate build.** The exact service and explicit outside-client checkouts build.
|
|
55
|
+
2. **Clean bootstrap.** A canonical daemon starts on a new database and the
|
|
56
|
+
client creates a user-named workspace over the explicit forest.
|
|
57
|
+
3. **Inspection.** The model performs successful retrievals, including READ,
|
|
58
|
+
before answering and names multiple inspected repository artifacts.
|
|
59
|
+
4. **Comprehension.** The report covers service, contracts/DSL, client/AG-UI,
|
|
60
|
+
repository topology, current-work evidence, and confidence-limiting gaps.
|
|
61
|
+
If the canonical forge is unavailable inside the run, it must say that the
|
|
62
|
+
current goal is unverified rather than promote archived GitHub history.
|
|
63
|
+
5. **Forensics.** The supported digest captures the database, packet, reasoning,
|
|
64
|
+
usage, and operation evidence used by the deterministic verdict.
|
|
43
65
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
3. **Automatic doctrine.** The project-root `AGENTS.md` appears in the model system packet without an explicit pick.
|
|
47
|
-
4. **Client YOLO (`--yolo`).** The loop surrenders a proposal to the client; the client synchronously accepts it, posts an explicit resume, and reaches a terminal result.
|
|
48
|
-
5. **Loop auto (`--auto`).** Execution authority remains with the loop; its proposal resolves internally without a client review or resume round-trip.
|
|
49
|
-
6. **Human review.** A proposal survives disconnect/reconnect and can be explicitly accepted or rejected.
|
|
50
|
-
7. **Model hot-swap.** Two configured aliases run in the same workspace and their turns record the selected models.
|
|
51
|
-
8. **Restart/resume.** After a daemon restart against the same database, the named workspace and worker retain their context and can complete another run.
|
|
52
|
-
9. **Comprehension.** The capable-model orientation report identifies the architecture, repository topology, current goal, meta-worker role, and missing or contradictory context with named evidence. Writing memory without delivering the requested report is RED.
|
|
53
|
-
10. **Forensics.** The database is digested through the supported digest tool and the preserved specimen contains enough evidence to audit every assertion above.
|
|
66
|
+
Proposal modes, reconnect, model hot-swap, and restart/resume are not asserted
|
|
67
|
+
by this executable slice. Expansion of the capstone remains tracked in #3.
|
|
54
68
|
|
|
55
69
|
Passing individual package tests or receiving HTTP 200 is insufficient. The user-visible client must remain usable and the requested terminal deliverable must be present.
|
|
56
70
|
|
|
57
71
|
## Evidence
|
|
58
72
|
|
|
59
|
-
Each
|
|
73
|
+
Each preserved campaign atomically claims `benchmarks/run<N>-orientation/` and writes:
|
|
60
74
|
|
|
61
|
-
- `workspace` —
|
|
75
|
+
- `workspace` — the generated workspace name;
|
|
76
|
+
- `prompt.md` — the exact orientation request;
|
|
77
|
+
- `client.json` and `client.stderr.log` — the client result and diagnostics;
|
|
62
78
|
- `service.stdout.log` and `service.stderr.log`;
|
|
63
|
-
- `phases.json` —
|
|
79
|
+
- `phases.json` — commands, timings, and exit statuses without secrets;
|
|
80
|
+
- `verdict.json` — lifecycle, publication, inspection, evidence, and coverage checks;
|
|
64
81
|
- `plurnk.db` — the preserved database;
|
|
65
82
|
- `digest/` — `digest.md`, `digest.json`, `reasoning.md`, and packet sections;
|
|
66
|
-
- `
|
|
83
|
+
- requiem artifacts in `digest/` when `--requiem` is requested.
|
|
67
84
|
|
|
68
85
|
The database is evidence, never the diagnostic interface. Assertions consume client output, AG-UI events, and digest artifacts.
|
|
69
86
|
|
|
70
87
|
## Posture
|
|
71
88
|
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
- Preserve both passing and failing specimens until explicitly curated.
|
|
89
|
+
- Execute in the foreground and fail hard.
|
|
90
|
+
- Preserve every failing specimen; preserve passing specimens when requested.
|
|
75
91
|
- Never reuse a database for a clean-bootstrap comparison.
|
|
76
92
|
- A provider/configuration/install failure is a gate failure, not a skipped model test.
|
|
77
|
-
-
|
|
93
|
+
- Never infer current work from an archived issue or an uninspected forge reference.
|
|
94
|
+
- File every cross-family defect on the canonical forge with its owning lane label and specimen path.
|
package/PLURNK_PERSONALITY.md
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
|
-
- You
|
|
2
|
-
- You
|
|
3
|
-
- You
|
|
4
|
-
- You
|
|
5
|
-
- You
|
|
6
|
-
- You
|
|
7
|
-
- You
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- Your commits add yourself, `Plurnk <plurnk@pm.me>` to the trailer. Branch freely, then merge if solo and PR if in a team.
|
|
13
|
-
- **Knowledgebase:** Curate a taxonomized, tagged, and topical worker:/// mind map of everything known about the project.
|
|
14
|
-
- **Plan:** Write a markdown checklist `- [x] Step 1\n- [ ] Step 2\n` in PLAN to list your prerogatives and priorities.
|
|
15
|
-
- **MODE:** Your continuing turn's ops follow the MODE Pattern: Mutate state, Observe the result, Do actions, End the turn.
|
|
16
|
-
- **Project:** Maintain a worker://~/project.md of project conventions, patterns, practices, and preferences.
|
|
17
|
-
- **Log:** Distill everything that's not relevant to your current concern and pack it where you can find it later.
|
|
18
|
-
- **Context:** Your Active Context is your workbench. FOLD, KILL, and distill to the knowledgebase to keep it relevant.
|
|
19
|
-
- **Errors:** READ the row the error points at. You can OPEN the "model" log item to find your mistake.
|
|
20
|
-
- **Workspace:** The Plurnk Service maintains your unlimited Extended Context forever. Curate, tag, and organize it well.
|
|
21
|
-
- **Delegation:** If your work naturally decomposes, spawn workers for the separate tasks.
|
|
22
|
-
- **Verification:** If your solution can be deterministically verified, prove your work before concluding.
|
|
23
|
-
- **Judgment:** If the prompt or the user preferences conflict with these rules, bend or break them.
|
|
24
|
-
- **Mission:** React and respond to the latest Plurnk Service User Prompts.
|
|
1
|
+
- You align with the user before consequential architectural, contract, or cross-project decisions.
|
|
2
|
+
- You answer inquiries and exploratory questions without changing code unless the user also asks for action.
|
|
3
|
+
- You preserve reusable knowledge and working state in searchable, folksonomically tagged knowledgebase entries.
|
|
4
|
+
- You verify unstable facts and answer from primary sources when possible.
|
|
5
|
+
- You follow modern standards and conventions unless a deliberate product property requires otherwise.
|
|
6
|
+
- You prove deterministically verifiable work before concluding.
|
|
7
|
+
- You commit completed repository changes as `Plurnk <plurnk@pm.me>` before concluding.
|
|
8
|
+
|
|
9
|
+
YOU MUST evaluate the prompt for completion conditions. If multiple conditions exist, maintain a Markdown checklist.
|
|
10
|
+
YOU MUST evaluate the prompt for decomposability, delegating to WORKers if any work is naturally divisible.
|
|
11
|
+
YOU MUST react and respond to the latest Plurnk Service User Prompts.
|
package/README.md
CHANGED
|
@@ -2,16 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
The plurnk metaproject layer, published — what the family shares that no single member owns.
|
|
4
4
|
|
|
5
|
-
**Membership primitives** (`import Meta from "@plurnk/plurnk-meta"`): the
|
|
5
|
+
**Membership primitives** (`import Meta from "@plurnk/plurnk-meta"`): the shared implementation of exact family identity, trust, attribution normalization, enumeration, and root resolution consumed by the four family-owned scanners (schemes, mimetypes, providers, execs). [SPEC.md](./SPEC.md) owns the complete contract ({§plugin-discovery}).
|
|
6
6
|
|
|
7
|
+
- `Meta.declaresKind(manifest, kind)` — accepts one exact string family identity; arrays claim no family ({§plugin-family-kind}).
|
|
7
8
|
- `Meta.isTrusted(packageName, env?)` — the `PLURNK_PLUGINS_TRUSTED_ONLY` gate: unset/`""`/`"0"` off; any value on, `@plurnk/*` always trusted plus a comma-separated allowlist.
|
|
9
|
+
- `Meta.normalizeAttribution(raw, packageName)` — normalize an always-on package declaration, including the reserved `@plurnk/` namespace rule ({§plugin-attribution}).
|
|
10
|
+
- `Meta.runtimeAttribution(source, context, packageName)` — pull and normalize an optional synchronous plugin hook for one provider emission attempt.
|
|
11
|
+
- `Meta.composeAttributions(...lists)` — flatten, deduplicate, and sort opaque tag lists.
|
|
8
12
|
- `Meta.packageDirs(nodeModulesDir)` — scope-agnostic, symlink-aware enumeration across Node's ancestor resolution chain as `{ dir, name }` candidates; the nearest package name wins. Ordering and filtering are the caller's policy.
|
|
9
13
|
- `Meta.nearestNodeModules(fromDir)` — walk up to the nearest `node_modules` holding the ecosystem (witness: `@plurnk` scope); `null` when absent.
|
|
10
14
|
|
|
11
|
-
**The teaching corpus**:
|
|
15
|
+
**The teaching corpus**: authored policy, Recap, built-in scheme, and conditional question sources resolved from this installed package. Meta owns the source bytes and membership; core owns admission and projection. See [`CORPUS.md`](./CORPUS.md) and {§teaching-corpus}.
|
|
12
16
|
|
|
13
17
|
**Family tooling** grows here (scaffolders, meta bins) — the published surface of the metaproject's management layer.
|
|
14
18
|
|
|
15
19
|
[`DOGFOOD.md`](./DOGFOOD.md) defines the whole-product, outside-client acceptance gate for daily-driver and release readiness.
|
|
16
20
|
|
|
17
|
-
Third-party plugin authors: your package is discovered
|
|
21
|
+
Third-party plugin authors: your package is discovered under any scope through one string `plurnk.kind`, enumerated by these primitives, and gated before import by the operator's trust knob — no registration with us required. An admitted package may declare always-on `plurnk.attribution` tags and its loaded plugin object may decide per provider attempt whether to return additional tags from `attributions(context)` ({§plugin-attribution}). MIT.
|
package/SPEC.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# plurnk-meta — Specification
|
|
2
|
+
|
|
3
|
+
Contract for facts shared across the open plurnk package family. Capability
|
|
4
|
+
frameworks own their family-specific declarations and runtime interfaces; this
|
|
5
|
+
package owns the installed-membership primitives they share and the published
|
|
6
|
+
teaching sources listed below.
|
|
7
|
+
|
|
8
|
+
## §teaching-corpus Published teaching sources
|
|
9
|
+
|
|
10
|
+
The package owns the authored defaults and exact membership below. Consumers
|
|
11
|
+
own admission, runtime projection, and model-facing placement; copying these
|
|
12
|
+
sources into a consuming package would create a second teaching owner.
|
|
13
|
+
|
|
14
|
+
| Source | Membership | Meta-owned content | Core read boundary |
|
|
15
|
+
| ------------------------------- | ---------- | -------------------------------------------------- | ------------------------------------------------------- |
|
|
16
|
+
| `PLURNK_PERSONALITY.md` | Required | First-run default operating policy | Policy bootstrap {§policy-sections} |
|
|
17
|
+
| `requirements.md` | Required | Default compact operational recap | Default user-slot Recap {§requirements} |
|
|
18
|
+
| `docs/log.md`, `docs/worker.md` | Required | Deep reference prose for reserved built-in schemes | Pull-doc materialization {§schemes-directory} |
|
|
19
|
+
| `docs/questions.md` | Required | Conditional operator-question reference prose | Enabled capability/teaching gate {§send-300-choices} |
|
|
20
|
+
|
|
21
|
+
Required is a package-membership statement, not unconditional packet
|
|
22
|
+
projection. Each source is read only at its consuming boundary; absence or an
|
|
23
|
+
unrelated read failure fails that boundary with the original cause. Consumers
|
|
24
|
+
resolve the exported membership exactly: they do not scan `docs/`, infer new
|
|
25
|
+
members from filenames, or treat a missing required source as empty teaching.
|
|
26
|
+
|
|
27
|
+
A file in `docs/` does not declare a capability. A built-in scheme document is
|
|
28
|
+
eligible only when its basename matches a registered reserved scheme; plugin
|
|
29
|
+
documentation remains owned by that plugin's manifest. `questions.md` is the
|
|
30
|
+
one explicit non-scheme document consumer. Retired or unregistered names do not
|
|
31
|
+
ship as speculative teaching. Manifest `documentation` is deliberately
|
|
32
|
+
optional: an absent field contributes no pull doc, while a present field is the
|
|
33
|
+
fallback only when meta owns no source for that scheme name.
|
|
34
|
+
|
|
35
|
+
## §plugin-discovery Installed capability discovery
|
|
36
|
+
|
|
37
|
+
```mermaid
|
|
38
|
+
flowchart LR
|
|
39
|
+
graph[Installed Node dependency graph] --> enumerate[Meta.packageDirs]
|
|
40
|
+
enumerate --> scanner[Family-owned scanner]
|
|
41
|
+
manifest[package.json plurnk manifest] --> scanner
|
|
42
|
+
policy[Meta.isTrusted] --> gate{Trusted?}
|
|
43
|
+
scanner --> gate
|
|
44
|
+
gate -->|yes| attribution[Meta.normalizeAttribution]
|
|
45
|
+
attribution --> family[Family-owned validation, loading, and registry]
|
|
46
|
+
gate -->|no| skipped[Skipped-package evidence]
|
|
47
|
+
family --> host[Composed host]
|
|
48
|
+
skipped --> host
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
| Layer | Owns | Does not own |
|
|
52
|
+
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
53
|
+
| `plurnk-meta` | Node package enumeration, exact capability-family identity, the one trust predicate, and package-attribution normalization. | Family fields, capability collisions, plugin imports, or presentation. |
|
|
54
|
+
| Family implementation | Family-field validation, deterministic ordering/collisions, trust enforcement before any plugin import, and trusted code loading. | A second trust or attribution policy, or cross-family composition. |
|
|
55
|
+
| Composed host | Cross-family arbitration and presentation of skipped-package evidence. | Re-parsing manifests or importing a declined package. |
|
|
56
|
+
|
|
57
|
+
The installed dependency graph is the compatibility boundary. Enumeration is
|
|
58
|
+
scope-agnostic and symlink-aware across Node's ancestor resolution chain; the
|
|
59
|
+
nearest package with a given package name wins. Installing a package makes a
|
|
60
|
+
valid declared capability discoverable. Environment values configure or bound
|
|
61
|
+
installed capabilities; they never manufacture package existence.
|
|
62
|
+
|
|
63
|
+
### §plugin-family-kind One package, one capability family
|
|
64
|
+
|
|
65
|
+
`package.json#plurnk.kind` is one exact string. Arrays and other shapes claim no
|
|
66
|
+
family. A package may declare multiple named capabilities inside its one
|
|
67
|
+
family-owned collection.
|
|
68
|
+
|
|
69
|
+
| `plurnk.kind` | Family-owned names |
|
|
70
|
+
| ------------- | -------------------------------------------------------- |
|
|
71
|
+
| `"exec"` | `runtimes[]` |
|
|
72
|
+
| `"mimetype"` | `handlers[]` |
|
|
73
|
+
| `"provider"` | singular `name` |
|
|
74
|
+
| `"scheme"` | `schemes[]`; singular `name` is the one-scheme shorthand |
|
|
75
|
+
|
|
76
|
+
Coordinated capabilities spanning families use explicit daemon-module
|
|
77
|
+
composition ({§module-lifecycle}); a multi-kind manifest is not a parallel
|
|
78
|
+
module mechanism.
|
|
79
|
+
|
|
80
|
+
### §plugin-attribution Plugin-authored attribution tags
|
|
81
|
+
|
|
82
|
+
| Surface | Contract |
|
|
83
|
+
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
84
|
+
| Static declaration | Optional `plurnk.attribution` is one non-empty string or an array of non-empty strings. `null`, absence, and an empty array normalize to no tags. A declaration is an always-on source for the admitted package. |
|
|
85
|
+
| Runtime declaration | A loaded plugin object may implement synchronous `attributions(context)`, returning the same declaration shape, `null`, or `undefined`. The hook is pulled once for each provider emission attempt; returning no tags omits that source. |
|
|
86
|
+
| Hook context | `workspaceId`, `workerId`, and `primaryWorkerId` are opaque strings; `loop`, `turn`, and `attempt` are positive sequence numbers. The hook receives no engine, database, trust, or mutation capability. |
|
|
87
|
+
| Trust | The family applies {§plugin-trust-boundary} before attribution validation or plugin import. Trust admits executable code; it does not make an authored tag truthful. |
|
|
88
|
+
| Normalization | `Meta.normalizeAttribution(raw, packageName)` and `Meta.runtimeAttribution(source, context, packageName)` produce readonly ordered lists. A malformed trusted declaration, malformed hook, or thrown hook fails at the package boundary. |
|
|
89
|
+
| Namespace reservation | A tag beginning `@plurnk/` is valid only when `packageName` also begins `@plurnk/`; a violating trusted package fails. Other tag vocabularies, collisions, and meanings are deliberately uninterpreted. |
|
|
90
|
+
| Discovery result | Each family returns `packageAttributions`, keyed once by package name. Only non-empty static lists for packages represented after family admission are present. |
|
|
91
|
+
| Host composition | The host flattens static and runtime lists from its admitted plugin objects, deduplicates and sorts the result, and treats it as an opaque folksonomy. It does not infer contribution, provenance, weight, trustworthiness, or causal value. |
|
|
92
|
+
| Published projections | Existing per-tag, per-handler, or name-keyed attribution fields may project the validated static declaration for 1.x compatibility; they do not own another policy. |
|
|
93
|
+
|
|
94
|
+
Manifest acquisition and static validation occur once in the family discovery
|
|
95
|
+
path. A composed host consumes the admitted package map and loaded plugin
|
|
96
|
+
objects without reopening a manifest or tracing tags through produced values.
|
|
97
|
+
|
|
98
|
+
### §plugin-trust-boundary One policy, enforcement before import
|
|
99
|
+
|
|
100
|
+
`Meta.isTrusted(packageName, env)` is the sole trust decision:
|
|
101
|
+
|
|
102
|
+
- unset, empty, or `"0"` `PLURNK_PLUGINS_TRUSTED_ONLY` trusts every installed
|
|
103
|
+
package;
|
|
104
|
+
- any other value trusts every `@plurnk/*` package plus the comma-separated
|
|
105
|
+
package-name allowlist in that value.
|
|
106
|
+
|
|
107
|
+
Every family scanner applies that predicate after reading the inert package
|
|
108
|
+
manifest and before importing or registering plugin code. An untrusted package
|
|
109
|
+
does not crash discovery: the family result preserves its package identity as
|
|
110
|
+
skipped evidence. The composed host decides how to present that evidence.
|
|
111
|
+
Direct framework consumers receive the same safe load boundary and can choose
|
|
112
|
+
their own presentation.
|
package/dist/index.d.ts
CHANGED
|
@@ -2,9 +2,38 @@ export interface PackageCandidate {
|
|
|
2
2
|
dir: string;
|
|
3
3
|
name: string;
|
|
4
4
|
}
|
|
5
|
+
export type PluginKind = "exec" | "mimetype" | "provider" | "scheme";
|
|
6
|
+
export type PluginAttributionDeclaration = string | string[];
|
|
7
|
+
export type PluginAttribution = readonly string[];
|
|
8
|
+
export type PackageAttributions = ReadonlyMap<string, PluginAttribution>;
|
|
9
|
+
export interface PluginAttributionContext {
|
|
10
|
+
readonly workspaceId: string;
|
|
11
|
+
readonly workerId: string;
|
|
12
|
+
readonly primaryWorkerId: string;
|
|
13
|
+
readonly loop: number;
|
|
14
|
+
readonly turn: number;
|
|
15
|
+
readonly attempt: number;
|
|
16
|
+
}
|
|
17
|
+
export interface PluginAttributionSource {
|
|
18
|
+
attributions?(context: PluginAttributionContext): PluginAttributionDeclaration | null | undefined;
|
|
19
|
+
}
|
|
20
|
+
export declare const TEACHING_CORPUS: Readonly<{
|
|
21
|
+
readonly personality: "PLURNK_PERSONALITY.md";
|
|
22
|
+
readonly requirements: "requirements.md";
|
|
23
|
+
readonly schemeDocs: Readonly<{
|
|
24
|
+
readonly log: "docs/log.md";
|
|
25
|
+
readonly worker: "docs/worker.md";
|
|
26
|
+
}>;
|
|
27
|
+
readonly questions: "docs/questions.md";
|
|
28
|
+
}>;
|
|
29
|
+
export type TeachingCorpusSource = typeof TEACHING_CORPUS.personality | typeof TEACHING_CORPUS.requirements | (typeof TEACHING_CORPUS.schemeDocs)[keyof typeof TEACHING_CORPUS.schemeDocs] | typeof TEACHING_CORPUS.questions;
|
|
5
30
|
export default class Meta {
|
|
6
31
|
#private;
|
|
32
|
+
static declaresKind(manifest: unknown, kind: PluginKind): boolean;
|
|
7
33
|
static isTrusted(packageName: string, env?: Record<string, string | undefined>): boolean;
|
|
34
|
+
static normalizeAttribution(raw: unknown, packageName: string): PluginAttribution;
|
|
35
|
+
static runtimeAttribution(source: unknown, context: PluginAttributionContext, packageName: string): PluginAttribution;
|
|
36
|
+
static composeAttributions(...lists: readonly PluginAttribution[]): PluginAttribution;
|
|
8
37
|
static packageDirs(nodeModulesDir: string): Promise<PackageCandidate[]>;
|
|
9
38
|
static nearestNodeModules(fromDir: string): string | null;
|
|
10
39
|
}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,gBAAgB;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAIrE,MAAM,MAAM,4BAA4B,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAC7D,MAAM,MAAM,iBAAiB,GAAG,SAAS,MAAM,EAAE,CAAC;AAClD,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;AAEzE,MAAM,WAAW,wBAAwB;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACpC,YAAY,CAAC,CAAC,OAAO,EAAE,wBAAwB,GAAG,4BAA4B,GAAG,IAAI,GAAG,SAAS,CAAC;CACrG;AASD,eAAO,MAAM,eAAe;0BACX,uBAAuB;2BACtB,iBAAiB;;sBAR1B,aAAa;yBACV,gBAAgB;;wBASb,mBAAmB;EACvB,CAAC;AAEZ,MAAM,MAAM,oBAAoB,GAC1B,OAAO,eAAe,CAAC,WAAW,GAClC,OAAO,eAAe,CAAC,YAAY,GACnC,CAAC,OAAO,eAAe,CAAC,UAAU,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,UAAU,CAAC,GAC5E,OAAO,eAAe,CAAC,SAAS,CAAC;AAKvC,MAAM,CAAC,OAAO,OAAO,IAAI;;IACrB,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAGhE;IAKD,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAe,GAAG,OAAO,CAKpG;IAED,MAAM,CAAC,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,iBAAiB,CAiBhF;IAKD,MAAM,CAAC,kBAAkB,CACrB,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,wBAAwB,EACjC,WAAW,EAAE,MAAM,GACpB,iBAAiB,CAcnB;IAED,MAAM,CAAC,mBAAmB,CAAC,GAAG,KAAK,EAAE,SAAS,iBAAiB,EAAE,GAAG,iBAAiB,CAIpF;IAkCD,OAAa,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAyB5E;IAED,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASxD;CACJ"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
// The metaproject layer's membership slice — the mechanics every discovery
|
|
2
|
-
// surface shares (
|
|
3
|
-
//
|
|
2
|
+
// surface shares ({§plugin-discovery} / {§operator-config-env-defaults}):
|
|
3
|
+
// - declaresKind: the ONE package → capability-family representation.
|
|
4
4
|
// - isTrusted: THE trust rule. One implementation; a second definition
|
|
5
5
|
// of membership trust anywhere in the family is a bug.
|
|
6
|
+
// - normalizeAttribution:
|
|
7
|
+
// one package declaration → one validated tag list.
|
|
6
8
|
// - packageDirs: scope-agnostic, symlink-aware enumeration of the Node
|
|
7
9
|
// resolution chain. Nearest package wins when npm splits
|
|
8
10
|
// a deployment across nested node_modules directories.
|
|
@@ -17,7 +19,26 @@
|
|
|
17
19
|
import { readdir } from "node:fs/promises";
|
|
18
20
|
import { existsSync } from "node:fs";
|
|
19
21
|
import path from "node:path";
|
|
22
|
+
const SCHEME_TEACHING = Object.freeze({
|
|
23
|
+
log: "docs/log.md",
|
|
24
|
+
worker: "docs/worker.md",
|
|
25
|
+
});
|
|
26
|
+
// {§teaching-corpus} — the authored package membership is one exported fact;
|
|
27
|
+
// consumers decide when and where each required source is projected.
|
|
28
|
+
export const TEACHING_CORPUS = Object.freeze({
|
|
29
|
+
personality: "PLURNK_PERSONALITY.md",
|
|
30
|
+
requirements: "requirements.md",
|
|
31
|
+
schemeDocs: SCHEME_TEACHING,
|
|
32
|
+
questions: "docs/questions.md",
|
|
33
|
+
});
|
|
34
|
+
const RESERVED_ATTRIBUTION_PREFIX = "@plurnk/";
|
|
35
|
+
const EMPTY_ATTRIBUTION = Object.freeze([]);
|
|
20
36
|
export default class Meta {
|
|
37
|
+
static declaresKind(manifest, kind) {
|
|
38
|
+
if (typeof manifest !== "object" || manifest === null)
|
|
39
|
+
return false;
|
|
40
|
+
return manifest.kind === kind;
|
|
41
|
+
}
|
|
21
42
|
// unset / "" / "0" → gate OFF: everything installed is trusted.
|
|
22
43
|
// any other value → gate ON: @plurnk/* always trusted, plus a comma-separated
|
|
23
44
|
// allowlist; "1" (naming no real package) = on, zero third-party.
|
|
@@ -29,6 +50,50 @@ export default class Meta {
|
|
|
29
50
|
return true;
|
|
30
51
|
return value.split(",").map((s) => s.trim()).includes(packageName);
|
|
31
52
|
}
|
|
53
|
+
static normalizeAttribution(raw, packageName) {
|
|
54
|
+
if (raw === undefined || raw === null)
|
|
55
|
+
return EMPTY_ATTRIBUTION;
|
|
56
|
+
const values = Array.isArray(raw) ? raw : [raw];
|
|
57
|
+
const firstParty = packageName.startsWith(RESERVED_ATTRIBUTION_PREFIX);
|
|
58
|
+
const tags = values.map((value) => {
|
|
59
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
60
|
+
throw new Error(`plugin '${packageName}': plurnk.attribution must be a non-empty string or string[]`);
|
|
61
|
+
}
|
|
62
|
+
if (value.startsWith(RESERVED_ATTRIBUTION_PREFIX) && !firstParty) {
|
|
63
|
+
throw new Error(`plugin '${packageName}': '${RESERVED_ATTRIBUTION_PREFIX}' is reserved for `
|
|
64
|
+
+ `${RESERVED_ATTRIBUTION_PREFIX}-scoped packages — '${packageName}' cannot claim '${value}'`);
|
|
65
|
+
}
|
|
66
|
+
return value;
|
|
67
|
+
});
|
|
68
|
+
return Object.freeze(tags);
|
|
69
|
+
}
|
|
70
|
+
// {§plugin-attribution} — one synchronous runtime pull with the same shape
|
|
71
|
+
// and sole namespace reservation as the static declaration. Tags remain
|
|
72
|
+
// opaque; this boundary validates structure, not meaning.
|
|
73
|
+
static runtimeAttribution(source, context, packageName) {
|
|
74
|
+
if (source === null || source === undefined)
|
|
75
|
+
return EMPTY_ATTRIBUTION;
|
|
76
|
+
const hook = source.attributions;
|
|
77
|
+
if (hook === undefined)
|
|
78
|
+
return EMPTY_ATTRIBUTION;
|
|
79
|
+
if (typeof hook !== "function") {
|
|
80
|
+
throw new TypeError(`plugin '${packageName}': attributions must be a function when present`);
|
|
81
|
+
}
|
|
82
|
+
let raw;
|
|
83
|
+
try {
|
|
84
|
+
raw = hook.call(source, context);
|
|
85
|
+
}
|
|
86
|
+
catch (cause) {
|
|
87
|
+
throw new Error(`plugin '${packageName}': attributions() failed`, { cause });
|
|
88
|
+
}
|
|
89
|
+
return Meta.normalizeAttribution(raw, packageName);
|
|
90
|
+
}
|
|
91
|
+
static composeAttributions(...lists) {
|
|
92
|
+
if (lists.length === 0)
|
|
93
|
+
return EMPTY_ATTRIBUTION;
|
|
94
|
+
const tags = [...new Set(lists.flat())].toSorted();
|
|
95
|
+
return tags.length === 0 ? EMPTY_ATTRIBUTION : Object.freeze(tags);
|
|
96
|
+
}
|
|
32
97
|
static async #packageDirsOne(nodeModulesDir) {
|
|
33
98
|
let entries;
|
|
34
99
|
try {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/docs/log.md
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
|
-
# `log://`
|
|
1
|
+
# `log://` - your worker's event history
|
|
2
2
|
|
|
3
|
-
Every operation
|
|
3
|
+
Every operation is recorded at `log:///<loop>/<turn>/<seq>`. The row identifies what happened and what came back. READ a row to retrieve its result body or apply a content matcher.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Log and catalog
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
7
|
+
- **Log** - operations and results in order.
|
|
8
|
+
- **Catalog** - `FIND(scheme:///**)` lists the resources a scheme currently holds.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Visibility
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- **FOLD** hides an open row's body. The row and body persist, and the row remains listed.
|
|
13
|
+
- **OPEN** reveals a folded row's body.
|
|
14
|
+
- A row's `tokens` is the size of its body: its current packet weight when open and its OPEN cost when folded.
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
- **OPEN** a folded row → restores its full body, spending from `tokensFree`. To revisit a result you folded too early — or READ the row directly with a matcher.
|
|
16
|
-
- **KILL** a row → erases it. Sparingly, for rows whose very existence (not just body) is noise.
|
|
16
|
+
OPEN and FOLD change packet visibility, not history. Applying the current state again or targeting a bodyless row is a successful no-op.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
## Deletion and capacity
|
|
19
|
+
|
|
20
|
+
KILL permanently erases a log row.
|
|
21
|
+
|
|
22
|
+
The Budget section reports only the packet ceiling, usage, percentage, and free capacity. Each
|
|
23
|
+
log row carries its own token weight. If a packet exceeds its ceiling, the engine folds eligible
|
|
24
|
+
open rows from the newest turn boundary; it never selects older history by relevance. Continued
|
|
25
|
+
overflow follows the reported recovery or hard-413 contract.
|
package/docs/questions.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Operator questions — `SEND[300]`
|
|
2
2
|
|
|
3
|
-
Enabled here: you may ask the operator when a decision is genuinely theirs to make. `<<SEND[300]:question:SEND` asks an open question; `<<SEND[300]:question;choice;choice:SEND` offers choices. Asking parks your
|
|
3
|
+
Enabled here: you may ask the operator when a decision is genuinely theirs to make. `<<SEND[300]:question:SEND` asks an open question; `<<SEND[300]:question;choice;choice:SEND` offers choices. Asking parks your loop; the answer arrives as the operator's next message — continue from it.
|
|
4
4
|
|
|
5
5
|
Choices are suggestions, never a constraint: the operator always has a free-text option regardless of what you list, so be ready for an answer outside your choices. Ask sparingly — one focused question carrying the context needed to answer it beats a chain of small asks.
|
package/docs/worker.md
CHANGED
|
@@ -1,11 +1,33 @@
|
|
|
1
|
-
# `worker://` —
|
|
1
|
+
# `worker://` — workers and their entries
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Workers inhabit one workspace. `worker://<name>` addresses a named worker; `worker://~` is the
|
|
4
|
+
current-worker control sigil; `worker://~/path` addresses your private entries; `worker:///path`
|
|
5
|
+
addresses the shared commons.
|
|
6
|
+
`WORK(worker://<name>):task` spawns a fresh worker with an empty log. `FORK(worker://<name>):task`
|
|
7
|
+
branches your current history. `SEND(worker://<name>):msg` messages a worker, waking it if idle;
|
|
8
|
+
`KILL(worker://<name>)` ends one. Workers share project files and the commons, while private entries
|
|
9
|
+
and conversation logs remain owner-scoped. A worker is born from WORK/FORK, never EDIT —
|
|
10
|
+
`EDIT(worker://<name>)` on the bare worker is rejected.
|
|
4
11
|
|
|
5
|
-
**
|
|
12
|
+
**The path is the discriminator.** `worker://<name>` with no path addresses a literal worker name
|
|
13
|
+
for WORK, FORK, SEND, READ, or KILL; `worker://~` addresses the caller for SEND or KILL.
|
|
14
|
+
The control form is exact: a trailing slash, userinfo, port, query, fragment, or request metadata
|
|
15
|
+
is invalid rather than ignored.
|
|
16
|
+
`worker://<name>/path` addresses an ancestry-visible named entry; `EDIT(worker://~/todo.md):…`
|
|
17
|
+
writes your own private entry.
|
|
6
18
|
|
|
7
|
-
**WORK to delegate, FORK to branch
|
|
19
|
+
**WORK to delegate, FORK to branch.** For fan-out, WORK a distinct-named worker per job. Each gets
|
|
20
|
+
a fresh task. FORK only to carry *your own* context down an alternate path.
|
|
8
21
|
|
|
9
|
-
**Loop: spawn once → park → collect on wake.**
|
|
22
|
+
**Loop: spawn once → park → collect on wake.** Spawn with
|
|
23
|
+
`<<WORK(worker://capital-checker):Find the capital of France from a primary source:WORK`, then
|
|
24
|
+
`<<SEND[202]:Awaiting capital-checker.:SEND` parks you. You wake when the worker concludes: its
|
|
25
|
+
result arrives open in your log as a `SEND` from `worker://capital-checker` — read it and continue.
|
|
26
|
+
Or pull it: `READ(worker://capital-checker)` returns the result, or `425` while it is running. Spawn
|
|
27
|
+
each worker exactly once. Fan-out uses distinct names, followed by one park. Each conclusion wakes
|
|
28
|
+
you with its delta.
|
|
10
29
|
|
|
11
|
-
**Concluding with live workers.** `SEND[200]` is refused (`409`) while you hold a live worker or
|
|
30
|
+
**Concluding with live workers.** `SEND[200]` is refused (`409`) while you hold a live worker or
|
|
31
|
+
open stream. The system packet lists them under `## Active Child Workers` and `## Child Streams`.
|
|
32
|
+
Either `SEND[202]` to await them or `KILL(worker://<name>)` the ones you no longer need. A same-turn
|
|
33
|
+
KILL followed by `SEND[200]` concludes cleanly.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plurnk/plurnk-meta",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "The plurnk metaproject layer, published: plugin-membership primitives (the ONE trust rule, scope-agnostic symlink-aware enumeration, deployment-root resolution), the project teaching corpus (personality, requirements, scheme docs), and the home for family tooling.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
".env.defaults",
|
|
12
12
|
"dist/**/*",
|
|
13
13
|
"README.md",
|
|
14
|
+
"SPEC.md",
|
|
14
15
|
"DOGFOOD.md",
|
|
15
16
|
"CORPUS.md",
|
|
16
17
|
"PLURNK_PERSONALITY.md",
|
|
@@ -33,12 +34,22 @@
|
|
|
33
34
|
"test:lint": "tsc --noEmit",
|
|
34
35
|
"test:unit": "node --conditions=plurnk-dev --test src/**/*.test.ts",
|
|
35
36
|
"test": "npm run test:lint && npm run test:unit",
|
|
37
|
+
"build:clean": "rm -rf dist",
|
|
36
38
|
"build:dist": "tsc -p tsconfig.build.json",
|
|
37
|
-
"build": "npm run build:dist",
|
|
39
|
+
"build": "npm run build:clean && npm run build:dist",
|
|
38
40
|
"prepack": "npm run build",
|
|
39
41
|
"prepublishOnly": "npm audit --audit-level=moderate && npm test"
|
|
40
42
|
},
|
|
41
43
|
"publishConfig": {
|
|
42
44
|
"access": "public"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://github.com/plurnk/plurnk-service/tree/main/plurnk-meta#readme",
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://repo.possumtech.com/plurnk/plurnk-service/issues"
|
|
49
|
+
},
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git+https://github.com/plurnk/plurnk-service.git",
|
|
53
|
+
"directory": "plurnk-meta"
|
|
43
54
|
}
|
|
44
55
|
}
|
package/requirements.md
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
YOU MUST ONLY use the Plurnk Service Grammar: <<OPsuffix[signal]?(target)?<scope>?:body?:OPsuffix
|
|
2
|
-
Example turn: <<PLAN:
|
|
2
|
+
Example turn: <<PLAN:Locate the definition before changing it.:PLAN <<FIND(src/**):@createCoder:FIND <<SEND[102]:Next, read the definition and its callers.:SEND
|
|
3
3
|
Close with SEND[200] only in a turn that performs no retrieval and has no surviving streams or workers.
|
package/docs/known.md
DELETED
package/docs/unknown.md
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
# `unknown://` — your open questions
|
|
2
|
-
|
|
3
|
-
The staging ground for the questions you author. Use it to decompose a non-trivial prompt into taxonomized, tagged, and topical entries — each an open question to resolve before you act — EDIT to pose, READ to retrieve, FIND to search, SEND to message an entry. It's the working half of the `known:///` knowledgebase: unknown holds what you're still chasing, known holds what you've established.
|