qualia-framework 7.0.0 → 7.0.1

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/CHANGELOG.md CHANGED
@@ -8,6 +8,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  > Note: git tags for historical versions were not retained; commit references are approximate
9
9
  > and dates reflect commit history rather than npm publish timestamps.
10
10
 
11
+ ## [7.0.1] - 2026-06-22 (/qualia-recall is OWNER-only)
12
+
13
+ ### Changed — `/qualia-recall` restricted to OWNER
14
+ - `recall.js` now resolves the install role up front and **refuses any role other
15
+ than `OWNER`** (exit 3, clear message) — a deterministic gate, not a prose note.
16
+ Previously the command was available to everyone and only the *vault content*
17
+ was role-filtered. Employees keep `/qualia-learn` (write side) and the read-only
18
+ memory MCP for ALL_ROLES wiki content; the curated cross-project recall is the
19
+ OWNER's surface. Skill description + body mark it OWNER-only; the employee
20
+ manual drops it from the command reference. `tests/recall.test.sh` now asserts
21
+ OWNER→allowed, EMPLOYEE/MANAGER/unknown→refused (20 cases). All 24 suites green.
22
+
11
23
  ## [7.0.0] - 2026-06-22 (v7 — the restructure is complete)
12
24
 
13
25
  The v7 milestone release. The 6.12→6.29 line landed the whole v7 restructure
package/bin/recall.js CHANGED
@@ -124,6 +124,18 @@ function main() {
124
124
  usage();
125
125
  process.exit(0);
126
126
  }
127
+
128
+ // OWNER-only command. The curated cross-project memory recall is the OWNER's
129
+ // surface; employees still have the read-only memory MCP for ALL_ROLES wiki
130
+ // content. Deterministic gate — not just a prose note. Exit 3 = forbidden.
131
+ const role = resolveRole(qualiaHome());
132
+ if (role !== "OWNER") {
133
+ process.stderr.write(
134
+ "/qualia-recall is OWNER-only. Ask Fawzi if you need a cross-project lookup.\n"
135
+ );
136
+ process.exit(3);
137
+ }
138
+
127
139
  const query = opts.terms.join(" ").trim();
128
140
  if (!query) {
129
141
  usage();
@@ -134,7 +146,6 @@ function main() {
134
146
  process.exit(2);
135
147
  }
136
148
 
137
- const role = resolveRole(qualiaHome());
138
149
  const knowledge = opts.scope === "vault" ? [] : searchKnowledge(query, opts.max);
139
150
  const vault = opts.scope === "knowledge" ? [] : searchVault(query, opts.max, role);
140
151
  const total = knowledge.length + vault.length;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qualia-framework",
3
- "version": "7.0.0",
3
+ "version": "7.0.1",
4
4
  "description": "Claude Code and Codex workflow framework by Qualia Solutions. Plan, build, verify, ship.",
5
5
  "bin": {
6
6
  "qualia-framework": "./bin/cli.js"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: qualia-recall
3
- description: "Recall curated prior lessons from the Qualia memory substrate — the knowledge layer + the qualia-memory vault, role-filtered. The read side of /qualia-learn. Triggers: 'recall', 'have we done this before', 'what did we learn about X', 'prior art', 'any notes on', 'check the vault'."
3
+ description: "OWNER-ONLY. Recall curated prior lessons from the Qualia memory substrate — the knowledge layer + the qualia-memory vault. The read side of /qualia-learn. Only the OWNER (Fawzi) can run it; recall.js refuses any other role. Triggers (OWNER only): 'recall', 'have we done this before', 'what did we learn about X', 'prior art', 'any notes on', 'check the vault'."
4
4
  allowed-tools:
5
5
  - Read
6
6
  - Grep
@@ -9,6 +9,11 @@ allowed-tools:
9
9
 
10
10
  # /qualia-recall — Recall Knowledge
11
11
 
12
+ > **OWNER-only.** `recall.js` resolves the install role and **refuses any role
13
+ > other than `OWNER`** (exit 3). This is a deterministic gate, not a convention —
14
+ > do not run it for an employee. Employees still have the read-only memory MCP for
15
+ > ALL_ROLES wiki content; the curated cross-project recall is the OWNER's surface.
16
+
12
17
  The **read side** of memory. `/qualia-learn` writes; `/qualia-recall` reads. One
13
18
  query, both stores:
14
19
 
@@ -1,5 +1,5 @@
1
1
  #!/bin/bash
2
- # recall.test.sh — bin/recall.js (read-side memory recall, role-filtered vault)
2
+ # recall.test.sh — bin/recall.js (read-side memory recall — OWNER-only command)
3
3
  # Run: bash tests/recall.test.sh
4
4
 
5
5
  PASS=0
@@ -44,7 +44,8 @@ cat > "$VAULT/wiki/_meta/access.md" <<'EOF'
44
44
  EOF
45
45
 
46
46
  export QUALIA_MEMORY_ROOT="$VAULT"
47
- RUN() { QUALIA_HOME="$HOME_DIR" "$@"; }
47
+ # recall is OWNER-only — every functional test runs as OWNER to reach the logic.
48
+ RUN() { QUALIA_HOME="$HOME_DIR" QUALIA_ROLE=OWNER "$@"; }
48
49
 
49
50
  # ── Invocation guards ──
50
51
  RUN $NODE "$RECALL" >/dev/null 2>&1; assert_exit "no query → exit 2" 2 $?
@@ -55,15 +56,15 @@ OUT=$(QUALIA_ROLE=OWNER RUN $NODE "$RECALL" zebrafish 2>&1); assert_exit "valid
55
56
  assert_contains "knowledge-layer hit" "$OUT" "learned-patterns.md"
56
57
  assert_contains "vault ALL_ROLES hit" "$OUT" "concepts/notes.md"
57
58
 
58
- # ── Role enforcement (the security boundary) ──
59
- OWNER_OUT=$(QUALIA_ROLE=OWNER RUN $NODE "$RECALL" zebrafish --scope vault 2>&1)
60
- assert_contains "OWNER sees OWNER_ONLY path" "$OWNER_OUT" "_meta/access.md"
61
- EMP_OUT=$(QUALIA_ROLE=EMPLOYEE RUN $NODE "$RECALL" zebrafish --scope vault 2>&1)
62
- assert_contains "EMPLOYEE still sees ALL_ROLES" "$EMP_OUT" "concepts/notes.md"
63
- assert_absent "EMPLOYEE blocked from OWNER_ONLY" "$EMP_OUT" "_meta/access.md"
64
- # fail-closed: no role config + no QUALIA_ROLERESTRICTED
65
- NOROLE_OUT=$(QUALIA_HOME="$VAULT" env -u QUALIA_ROLE $NODE "$RECALL" zebrafish --scope vault 2>&1)
66
- assert_absent "RESTRICTED (fail-closed) blocked from OWNER_ONLY" "$NOROLE_OUT" "_meta/access.md"
59
+ # ── OWNER-only gate (the command itself is restricted, not just vault content) ──
60
+ OWNER_OUT=$(QUALIA_HOME="$HOME_DIR" QUALIA_ROLE=OWNER $NODE "$RECALL" zebrafish --scope vault 2>&1); assert_exit "OWNER → allowed (exit 0)" 0 $?
61
+ assert_contains "OWNER sees vault content" "$OWNER_OUT" "concepts/notes.md"
62
+ QUALIA_HOME="$HOME_DIR" QUALIA_ROLE=EMPLOYEE $NODE "$RECALL" zebrafish >/dev/null 2>&1; assert_exit "EMPLOYEE → refused (exit 3)" 3 $?
63
+ EMP_MSG=$(QUALIA_HOME="$HOME_DIR" QUALIA_ROLE=EMPLOYEE $NODE "$RECALL" zebrafish 2>&1)
64
+ assert_contains "EMPLOYEE refusal names OWNER-only" "$EMP_MSG" "OWNER-only"
65
+ QUALIA_HOME="$HOME_DIR" QUALIA_ROLE=MANAGER $NODE "$RECALL" zebrafish >/dev/null 2>&1; assert_exit "MANAGER refused (exit 3)" 3 $?
66
+ # unknown role (no QUALIA_ROLE, no config) fail-closed refused
67
+ env -u QUALIA_ROLE QUALIA_HOME="$HOME_DIR" $NODE "$RECALL" zebrafish >/dev/null 2>&1; assert_exit "unknown role (fail-closed) refused (exit 3)" 3 $?
67
68
 
68
69
  # ── JSON shape ──
69
70
  JSON=$(QUALIA_ROLE=OWNER RUN $NODE "$RECALL" zebrafish --json 2>&1)