@fyso/awareness-framework 0.2.0 → 0.3.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.
@@ -0,0 +1,82 @@
1
+ import { normalizeSearchText } from './text.js';
2
+
3
+ export function activeMemoryCandidates(content) {
4
+ const prunedTexts = prunedMemoryCandidateTexts(content);
5
+ return parseMemoryCandidates(content).filter((candidate) => !prunedTexts.has(normalizeMemoryCandidateText(candidate.text)));
6
+ }
7
+
8
+ export function isPrunedMemoryText(content, text) {
9
+ return prunedMemoryCandidateTexts(content).has(normalizeMemoryCandidateText(text));
10
+ }
11
+
12
+ export function memoryCandidateExists(content, text, evidence) {
13
+ const candidates = extractMarkdownSection(content, 'Promotion Candidates');
14
+ return candidates.split('\n').some((line) => line.includes(`: ${text} (evidence: ${evidence})`));
15
+ }
16
+
17
+ export function memoryCandidateTextExists(content, text) {
18
+ const key = normalizeMemoryCandidateText(text);
19
+ return parseMemoryCandidates(content).some((candidate) => normalizeMemoryCandidateText(candidate.text) === key);
20
+ }
21
+
22
+ export function repeatedMemoryCandidateSuggestions(content, minCount) {
23
+ const grouped = new Map();
24
+ for (const candidate of activeMemoryCandidates(content)) {
25
+ const key = normalizeMemoryCandidateText(candidate.text);
26
+ const group = grouped.get(key) || { text: candidate.text, count: 0, evidence: [] };
27
+ group.count += 1;
28
+ group.evidence.push(candidate.evidence);
29
+ grouped.set(key, group);
30
+ }
31
+
32
+ return [...grouped.values()]
33
+ .filter((group) => group.count >= minCount)
34
+ .map((group) => ({
35
+ text: group.text,
36
+ count: group.count,
37
+ evidence: [...new Set(group.evidence)].join('; '),
38
+ }))
39
+ .sort((left, right) => right.count - left.count || left.text.localeCompare(right.text));
40
+ }
41
+
42
+ function parseMemoryCandidates(content) {
43
+ const candidates = [];
44
+ const candidatePattern = /^- \d{4}-\d{2}-\d{2}: (.+) \(evidence: (.+)\)$/;
45
+ for (const rawLine of extractMarkdownSection(content, 'Promotion Candidates').split('\n')) {
46
+ const match = candidatePattern.exec(rawLine.trim());
47
+ if (!match) continue;
48
+ candidates.push({
49
+ line: match[0],
50
+ text: match[1],
51
+ evidence: match[2],
52
+ });
53
+ }
54
+ return candidates;
55
+ }
56
+
57
+ function prunedMemoryCandidateTexts(content) {
58
+ const pruned = new Set();
59
+ const prunedPattern = /^- \d{4}-\d{2}-\d{2}: (.+) \(reason: .+; evidence: .+\)$/;
60
+ for (const rawLine of extractMarkdownSection(content, 'Pruned Or Revised').split('\n')) {
61
+ const match = prunedPattern.exec(rawLine.trim());
62
+ if (match) pruned.add(normalizeMemoryCandidateText(match[1]));
63
+ }
64
+ return pruned;
65
+ }
66
+
67
+ function normalizeMemoryCandidateText(text) {
68
+ return normalizeSearchText(text);
69
+ }
70
+
71
+ function extractMarkdownSection(content, section) {
72
+ const lines = content.split('\n');
73
+ const start = lines.findIndex((line) => line.trimEnd() === `## ${section}`);
74
+ if (start === -1) return '';
75
+
76
+ const body = [];
77
+ for (const line of lines.slice(start + 1)) {
78
+ if (line.startsWith('## ')) break;
79
+ body.push(line);
80
+ }
81
+ return body.join('\n').replace(/^\n/, '');
82
+ }
package/src/text.js ADDED
@@ -0,0 +1,35 @@
1
+ const RECALL_ALIASES = {
2
+ memoria: ['memory'],
3
+ memorias: ['memory'],
4
+ memory: ['memoria', 'memorias'],
5
+ user: ['usuario', 'usuarios'],
6
+ users: ['usuario', 'usuarios'],
7
+ usuario: ['user', 'users'],
8
+ usuarios: ['user', 'users'],
9
+ };
10
+
11
+ export function normalizeSearchText(text) {
12
+ return String(text)
13
+ .normalize('NFD')
14
+ .replace(/[\u0300-\u036f]/g, '')
15
+ .toLowerCase()
16
+ .replace(/[^a-z0-9._-]+/g, ' ')
17
+ .replace(/\s+/g, ' ')
18
+ .trim();
19
+ }
20
+
21
+ export function recallTermGroups(query) {
22
+ return normalizeSearchText(query)
23
+ .split(/\s+/)
24
+ .filter(Boolean)
25
+ .map((term) => new Set([term, ...recallTokenVariants(term), ...(RECALL_ALIASES[term] || [])]))
26
+ .map((terms) => [...terms].filter(Boolean))
27
+ .filter((terms, index, groups) => groups.findIndex((group) => group[0] === terms[0]) === index);
28
+ }
29
+
30
+ function recallTokenVariants(term) {
31
+ const variants = [];
32
+ if (term.endsWith('es') && term.length > 4) variants.push(term.slice(0, -2));
33
+ if (term.endsWith('s') && term.length > 3) variants.push(term.slice(0, -1));
34
+ return variants;
35
+ }
@@ -6,7 +6,7 @@ You operate in a multi-task, multi-agent environment. Before doing work, load th
6
6
 
7
7
  - Awareness board: `~/.agents/awareness/current.md`
8
8
  - Daily worklog: `~/.agents/worklog/YYYY-MM-DD.md`
9
- - Optional durable memory: `~/.agents/memory/`
9
+ - Durable memory and review candidates: `~/.agents/memory/`
10
10
  - Optional narrow user memory: `~/.agents/memory/users/<user>.md` or scoped channel equivalent
11
11
  - Optional evaluation notes: `~/.agents/evaluations/YYYY-MM-DD.md`
12
12
  - Runtime hook and scheduler events: `~/.agents/runtime/`
@@ -20,18 +20,27 @@ You operate in a multi-task, multi-agent environment. Before doing work, load th
20
20
  5. When concrete progress happens, append to the daily worklog.
21
21
  6. When state changes, update the awareness board.
22
22
  7. Before handoff, run `awareness handoff` if available; otherwise make the awareness board reflect the exact current state and append a final worklog entry.
23
- 8. At end of day, prepare a task-grouped summary for human review.
24
- 9. Treat hook and scheduler runtime events as diagnostics only; they do not replace task worklog entries.
25
- 10. For multi-user channels, keep context scoped by channel and store only narrow user facts in `memory/users/<user>.md`.
23
+ 8. When evaluation or handoff exposes repeated friction, review memory candidates with `awareness memory candidates` or `awareness memory review`.
24
+ 9. At end of day, prepare a task-grouped summary for human review, including memory candidates and pattern suggestions.
25
+ 10. Treat hook and scheduler runtime events as diagnostics only; they do not replace task worklog entries.
26
+ 11. For multi-user channels, keep context scoped by channel and store only narrow user facts in `memory/users/<user>.md`.
26
27
 
27
28
  ## Rules
28
29
 
29
30
  - Keep the worklog append-only.
30
31
  - Do not invent task IDs.
31
32
  - Record evidence: paths, commands, test results, commits, PRs, deployments, blockers.
32
- - Prefer CLI maintenance commands (`awareness focus`, `awareness log`, `awareness handoff`, `awareness evaluate`) when available.
33
+ - Prefer CLI maintenance commands (`awareness focus`, `awareness log`, `awareness handoff`, `awareness evaluate`, `awareness memory candidates`, `awareness memory review`) when available.
34
+ - Let evaluations and schedules record promotion candidates, but promote durable memory only with explicit evidence through `awareness memory promote`.
35
+ - Promote repeated candidates as `pattern` only after `awareness memory review` or equivalent evidence shows repetition.
36
+ - Promote direct user preferences promptly when they affect future collaboration.
33
37
  - Use `awareness user note` only for short, evidence-backed participant facts such as nicknames, repeated questions, topics, or explicit preferences.
34
- - Use `awareness hook run` and `awareness schedule run` only for low-noise maintenance; do not let them post externally or promote long-term memory silently.
38
+ - Use `awareness hook run` and `awareness schedule run` only for low-noise maintenance; do not let them post externally or silently promote long-term memory.
35
39
  - Keep private state out of version control.
36
40
  - Ask before posting worklogs, comments, status changes, or summaries to external systems.
37
41
  - Propose framework improvements through reviewed changes, not hidden local edits.
42
+
43
+ - Use `awareness remember` for explicit observations that should enter memory review.
44
+ - Use `awareness recall QUERY` before repeating uncertain or previously solved work.
45
+ - Use `awareness forget --text TEXT --reason REASON --evidence EVIDENCE` when memory is stale, wrong, or superseded.
46
+ - Use `awareness improve` after material work or process friction to run evaluation plus memory review.
@@ -6,6 +6,6 @@ Read and follow the canonical private protocol at:
6
6
 
7
7
  If your CLI does not expand `@` imports automatically, open that file explicitly before starting work.
8
8
 
9
- Treat imported awareness files as session-start snapshots. If the Awareness CLI is available, run `awareness status` or `awareness check` at session start, `awareness refresh` when parallel work may have changed state, and `awareness handoff` before returning control.
9
+ Treat imported awareness files as session-start snapshots. If the Awareness CLI is available, run `awareness status` or `awareness check` at session start, `awareness refresh` when parallel work may have changed state, `awareness memory review` when evaluating repeated candidates, and `awareness handoff` before returning control.
10
10
 
11
11
  Keep this wrapper small. The framework should live in versioned methodology docs, and live operational state should stay private.
@@ -25,3 +25,11 @@
25
25
  ## Methodology Observations
26
26
 
27
27
  - Anything that made the awareness or worklog process better or worse
28
+
29
+ ## Memory Review
30
+
31
+ - New promotion candidates:
32
+ - Repeated candidates or suggested patterns:
33
+ - Promotions made:
34
+ - Needs user confirmation:
35
+ - Candidates to prune or leave short-term:
@@ -22,6 +22,9 @@
22
22
 
23
23
  - Short-term observations to keep short-term:
24
24
  - Long-term memory candidates:
25
+ - Repeated candidates from `awareness memory review`:
26
+ - Suggested pattern promotions:
27
+ - Promotion command and evidence:
25
28
  - Memory to prune or revise:
26
29
  - User confirmation needed:
27
30
 
@@ -29,7 +32,7 @@
29
32
 
30
33
  - Awareness cleanup:
31
34
  - Worklog correction:
32
- - Long-term memory promotion:
35
+ - Long-term memory promotion, candidate, or prune decision:
33
36
  - Personality update:
34
37
  - Framework PR candidate:
35
38
 
@@ -3,7 +3,7 @@
3
3
  - Updated: never
4
4
  - Scope: Local private state; do not commit
5
5
 
6
- This file stores durable, curated memory that improves future collaboration. Add entries only when they are user-confirmed, repeated, or operationally important.
6
+ This file stores durable, curated memory that improves future collaboration. Evaluations may add promotion candidates automatically, but durable entries should be promoted only when they are user-confirmed, repeated, or operationally important.
7
7
 
8
8
  ## Preferences
9
9
 
@@ -25,6 +25,19 @@ This file stores durable, curated memory that improves future collaboration. Add
25
25
 
26
26
  - None yet.
27
27
 
28
+ ## Review Notes
29
+
30
+ - Use `awareness memory candidates` to inspect raw candidates.
31
+ - Use `awareness memory review` to surface repeated candidates that may deserve promotion as `Patterns`.
32
+ - Use `awareness memory promote --kind preference|pattern|project|review --text TEXT --evidence EVIDENCE` after review.
33
+ - Repeated candidates may share the same text with distinct evidence; do not collapse them before review.
34
+
35
+ ## Event Log
36
+
37
+ - Append-only audit history: `memory/events.jsonl`
38
+ - Markdown sections are readable projections.
39
+ - Do not hand-edit event history.
40
+
28
41
  ## Pruned Or Revised
29
42
 
30
43
  - None yet.
@@ -35,3 +48,4 @@ This file stores durable, curated memory that improves future collaboration. Add
35
48
  - Do not promote one-off guesses without repeated evidence.
36
49
  - Direct user instructions override memory.
37
50
  - Remove or soften stale memory.
51
+ - Keep promotion evidence concise and linkable.