agent-bios 0.19.0 → 0.19.2
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/DEPENDENCIES.md +27 -27
- package/INSTALL.md +4 -4
- package/README.md +58 -28
- package/claude/CLAUDE.md +1 -1
- package/claude/guides/claude-prompting.md +1 -1
- package/claude/guides/cli-multi-model-workflow.md +3 -3
- package/claude/guides/documentation-hygiene.md +3 -0
- package/claude/guides/gpt-prompting.md +1 -1
- package/claude/guides/korean-writing.md +153 -0
- package/claude/guides/learning-flow.md +4 -4
- package/claude/guides/session-distill-workflow.md +8 -8
- package/claude/guides/slide-writing/RUNBOOK.md +5 -5
- package/claude/skills/repo-charter/SKILL.md +3 -3
- package/claude/skills/understand/SKILL.md +58 -28
- package/codex/AGENTS.md +1 -1
- package/codex/guides/claude-prompting.md +1 -1
- package/codex/guides/cli-multi-model-workflow.md +3 -3
- package/codex/guides/documentation-hygiene.md +3 -0
- package/codex/guides/gpt-prompting.md +1 -1
- package/codex/guides/korean-writing.md +153 -0
- package/codex/guides/learning-flow.md +4 -4
- package/codex/guides/session-distill-workflow.md +8 -8
- package/codex/guides/slide-writing/RUNBOOK.md +5 -5
- package/compose/app_bridge/SKILL.md +12 -12
- package/compose/app_bridge/scripts/bridge.py +15 -7
- package/compose/assemble.py +5 -5
- package/compose/bootstrap/SKILL.md +18 -18
- package/compose/canary.sh +4 -4
- package/compose/check-domains.py +6 -6
- package/compose/corpus-state.py +16 -1168
- package/compose/corpus.py +13 -402
- package/compose/corpus_app.py +14 -450
- package/compose/corpus_catalog.py +15 -926
- package/compose/corpus_import.py +14 -523
- package/compose/corpus_install.py +14 -1841
- package/compose/corpus_session.py +16 -848
- package/compose/corpus_setup.py +16 -670
- package/compose/corpus_setup_cli.py +15 -577
- package/compose/corpus_setup_i18n.py +20 -318
- package/compose/corpus_setup_ui.py +18 -631
- package/compose/corpus_store.py +16 -1621
- package/compose/corpus_transaction.py +15 -284
- package/compose/corpus_ui.py +17 -972
- package/compose/corpus_ui_runtime.py +16 -274
- package/compose/corpus_understand.py +13 -520
- package/compose/domains.json +2 -1
- package/compose/instructions-state.py +1175 -0
- package/compose/instructions.py +409 -0
- package/compose/instructions_app.py +464 -0
- package/compose/instructions_catalog.py +931 -0
- package/compose/instructions_import.py +529 -0
- package/compose/instructions_install.py +1866 -0
- package/compose/instructions_session.py +852 -0
- package/compose/instructions_setup.py +676 -0
- package/compose/instructions_setup_cli.py +586 -0
- package/compose/instructions_setup_i18n.py +324 -0
- package/compose/instructions_setup_ui.py +647 -0
- package/compose/instructions_store.py +1668 -0
- package/compose/instructions_transaction.py +306 -0
- package/compose/instructions_ui.py +975 -0
- package/compose/instructions_ui_runtime.py +278 -0
- package/compose/instructions_understand.py +678 -0
- package/compose/register-hooks.py +1 -1
- package/compose/setup/START.md +24 -13
- package/docs/advanced-launch.md +11 -11
- package/docs/instructions-compatibility.md +86 -0
- package/docs/{corpus.md → instructions.md} +35 -8
- package/docs/recovery.md +8 -8
- package/docs/releases/0.19.2.md +38 -0
- package/docs/session-model.md +23 -20
- package/docs/setup.md +42 -25
- package/docs/understand.md +57 -9
- package/install.sh +70 -69
- package/launch/agent-launch.py +306 -295
- package/launch/agent-launch.toml +2 -2
- package/launch/i18n/en.toml +55 -55
- package/launch/i18n/ja.toml +56 -56
- package/launch/i18n/ko.toml +56 -56
- package/launch/shell_integration.py +4 -4
- package/learn/collect-learning.py +10 -10
- package/learn/learning.schema.json +1 -1
- package/learn/migrate-learnings.py +51 -51
- package/package.json +27 -11
- package/provenance.json +1 -1
- /package/docs/assets/{corpus-studio.svg → instructions-studio.svg} +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Private captures are retained; promotion suppression is a snapshot projection.
|
|
3
3
|
|
|
4
|
-
The default entrypoint performs no source deletion.
|
|
4
|
+
The default entrypoint performs no source deletion. InstructionsStore requires exact
|
|
5
5
|
source and replacement evidence before omitting a duplicate from one snapshot.
|
|
6
6
|
The functions below implement only the explicit AGENT_BIOS_LEGACY_INSTALL=1
|
|
7
7
|
compatibility path, whose removal contract is described here.
|
|
8
8
|
|
|
9
|
-
After a push lands, a learning that was promoted into the shared
|
|
10
|
-
loaded from the
|
|
9
|
+
After a push lands, a learning that was promoted into the shared instructions are now
|
|
10
|
+
loaded from the instructions — its personal copy (written by `learn!`,
|
|
11
11
|
learn/collect-learning.py) would double-load. This user-side tool removes the
|
|
12
12
|
absorbed personal copy, and ONLY it (never the user's hand-written entry
|
|
13
13
|
CLAUDE.md `## Personal` section).
|
|
@@ -19,11 +19,11 @@ install must NOT trigger removal — that would silently lose the learning. When
|
|
|
19
19
|
unsure, KEEP (a kept duplicate is redundant; a wrong removal is data loss).
|
|
20
20
|
|
|
21
21
|
HOW THAT RULE IS ENFORCED (contract v2): audience metadata SELECTS candidates,
|
|
22
|
-
presence in the deployed
|
|
22
|
+
presence in the deployed instructions AUTHORIZES the delete. Metadata is a build-time
|
|
23
23
|
projection — it cannot see that this user runs a package or version whose bundle
|
|
24
24
|
never received the promoted bullet — so it is never the authority for an
|
|
25
25
|
irreversible act. Every uncertainty resolves to KEEP: a foreign package we
|
|
26
|
-
cannot confirm, an audience miss, an anchor absent from the
|
|
26
|
+
cannot confirm, an audience miss, an anchor absent from the instructions, a v1 record
|
|
27
27
|
with no anchor to verify.
|
|
28
28
|
|
|
29
29
|
Candidate selection (mirrors compose/assemble.py `kept`): universal tier
|
|
@@ -33,7 +33,7 @@ is one install shape — what used to be a "full" install is every domain
|
|
|
33
33
|
selected — so a selection always answers this.
|
|
34
34
|
|
|
35
35
|
Run per host (mirrors collect-learning: --host + --config-dir); install.sh calls
|
|
36
|
-
it after the
|
|
36
|
+
it after the instructions deploy. Manifest absent/empty -> no-op.
|
|
37
37
|
"""
|
|
38
38
|
import argparse
|
|
39
39
|
import importlib.util
|
|
@@ -50,7 +50,7 @@ import pkgid # noqa: E402 (package-identity primitive owned by compose/)
|
|
|
50
50
|
import assemble # noqa: E402 (owns the atomic-replace primitive both packages write with)
|
|
51
51
|
|
|
52
52
|
REPO = pathlib.Path(__file__).resolve().parent.parent
|
|
53
|
-
# Same home compose/
|
|
53
|
+
# Same home compose/instructions-state.py uses; the canary writes its activation proof here.
|
|
54
54
|
STATE_DIR = pathlib.Path(os.environ.get("AGENT_BIOS_STATE_DIR")
|
|
55
55
|
or pathlib.Path.home() / ".local/share/agent-bios")
|
|
56
56
|
MANIFEST = REPO / "learn" / "promotions.json"
|
|
@@ -58,7 +58,7 @@ UNIVERSAL_TIERS = frozenset({"core", "infra"}) # == assemble.audience UNIVERSAL
|
|
|
58
58
|
# learning_id inside a personal bullet's TRAILING comment (collect-learning
|
|
59
59
|
# prose_bullet: "... <!-- learning_id: <uuid> created: <ts> -->"). Anchored to
|
|
60
60
|
# end-of-line so a lesson body that quotes a `<!-- learning_id: … -->` string
|
|
61
|
-
# can never shadow the bullet's own id (this
|
|
61
|
+
# can never shadow the bullet's own id (this instructions are about agent tooling).
|
|
62
62
|
BULLET_LID_RE = re.compile(r"<!--\s*learning_id:\s*([0-9a-fA-F-]+)[^>]*-->\s*$")
|
|
63
63
|
|
|
64
64
|
|
|
@@ -120,22 +120,22 @@ def make_in_bundle(selection):
|
|
|
120
120
|
return in_bundle
|
|
121
121
|
|
|
122
122
|
|
|
123
|
-
def
|
|
124
|
-
"""Files and dirs that hold the DEPLOYED
|
|
123
|
+
def instructions_surfaces(home):
|
|
124
|
+
"""Files and dirs that hold the DEPLOYED instructions for this host.
|
|
125
125
|
|
|
126
126
|
Deliberately excludes `personal/` — the user's own copy of a promoted
|
|
127
127
|
learning quotes the same lesson, so searching it would find the very thing
|
|
128
128
|
we are deciding whether to delete and always answer yes.
|
|
129
129
|
"""
|
|
130
|
-
texts = [home / "central" / "bundle.md", # the assembled
|
|
130
|
+
texts = [home / "central" / "bundle.md", # the assembled instructions
|
|
131
131
|
home / "CLAUDE.md", home / "AGENTS.md"] # entry files, for a pre-convergence layout
|
|
132
132
|
dirs = [home / "central" / d for d in ("guides", "hooks", "agents")]
|
|
133
133
|
dirs += [home / d for d in ("guides", "hooks", "agents")]
|
|
134
134
|
return texts, dirs
|
|
135
135
|
|
|
136
136
|
|
|
137
|
-
def
|
|
138
|
-
"""A
|
|
137
|
+
def instructions_text(path, collect=None):
|
|
138
|
+
"""A instructions file's text with the user's personal region removed.
|
|
139
139
|
|
|
140
140
|
On codex the personal copy lives INSIDE AGENTS.md, and a promoted bullet is
|
|
141
141
|
written FROM the user's lesson — so its anchor can legitimately appear in
|
|
@@ -165,26 +165,26 @@ def anchor_names_a_file(anchor):
|
|
|
165
165
|
|
|
166
166
|
|
|
167
167
|
def placed_here(home, anchor, collect=None):
|
|
168
|
-
"""Is the promoted item REALLY in this user's deployed
|
|
168
|
+
"""Is the promoted item REALLY in this user's deployed instructions?
|
|
169
169
|
|
|
170
170
|
This is the authorization for an irreversible delete, so it asks the
|
|
171
171
|
filesystem rather than trusting build-time audience metadata, which is a
|
|
172
172
|
projection that goes stale the moment packages or versions diverge. A whole
|
|
173
173
|
guide/hook/agent placement is a deployed file; a bullet placement is its
|
|
174
|
-
anchor appearing in the deployed
|
|
174
|
+
anchor appearing in the deployed instructions text.
|
|
175
175
|
"""
|
|
176
176
|
if not isinstance(anchor, str) or not anchor:
|
|
177
177
|
return False
|
|
178
|
-
texts, dirs =
|
|
178
|
+
texts, dirs = instructions_surfaces(home)
|
|
179
179
|
if anchor_names_a_file(anchor):
|
|
180
180
|
# A whole-file placement is proven by the deployed FILE and by nothing else. It
|
|
181
|
-
# used to fall through to the text scan below, where any
|
|
181
|
+
# used to fall through to the text scan below, where any instructions document that
|
|
182
182
|
# merely NAMES the guide counted as proof the guide was installed — and the
|
|
183
|
-
#
|
|
183
|
+
# instructions names its guides constantly. This is the reachable case rather than the
|
|
184
184
|
# hypothetical one: the live manifest's only anchor is `tooling-gotchas.md`.
|
|
185
185
|
return any((d / anchor).is_file() for d in dirs)
|
|
186
186
|
for f in texts:
|
|
187
|
-
if f.is_file() and anchor in
|
|
187
|
+
if f.is_file() and anchor in instructions_text(f, collect):
|
|
188
188
|
return True
|
|
189
189
|
return False
|
|
190
190
|
|
|
@@ -277,10 +277,10 @@ def prune_codex_prose(home, remove_ids, collect, dry):
|
|
|
277
277
|
return removed
|
|
278
278
|
|
|
279
279
|
|
|
280
|
-
def
|
|
281
|
-
"""Is the shared
|
|
280
|
+
def claude_instructions_loaded(home, state_dir=None):
|
|
281
|
+
"""Is the shared instructions actually LOADED for this claude home?
|
|
282
282
|
|
|
283
|
-
Removing a personal copy while the
|
|
283
|
+
Removing a personal copy while the instructions copy is not loaded makes the rule
|
|
284
284
|
vanish (Review F2). The entry import line is necessary and NOT sufficient. Testing
|
|
285
285
|
whether the file contains `@central/bundle.md` also passes on the string in a
|
|
286
286
|
fenced block or in prose, and no reading of the file can see an import the
|
|
@@ -317,11 +317,11 @@ def collect_central_import():
|
|
|
317
317
|
return "@central/bundle.md"
|
|
318
318
|
|
|
319
319
|
|
|
320
|
-
def migrate(home, host, promotions, in_bundle, collect, dry=False,
|
|
320
|
+
def migrate(home, host, promotions, in_bundle, collect, dry=False, instructions_loaded=True):
|
|
321
321
|
"""Remove personal copies of promoted+in-bundle learnings present locally.
|
|
322
|
-
|
|
322
|
+
instructions_loaded=False (the instructions are not actually loaded for this host) -> keep
|
|
323
323
|
everything (never orphan a personal copy)."""
|
|
324
|
-
if not
|
|
324
|
+
if not instructions_loaded:
|
|
325
325
|
return {"removed": 0, "jsonl_removed": 0, "prose_removed": 0,
|
|
326
326
|
"kept_not_in_bundle": 0, "skipped": "corpus-not-loaded"}
|
|
327
327
|
jsonl = home / "personal" / "learnings.jsonl"
|
|
@@ -339,7 +339,7 @@ def migrate(home, host, promotions, in_bundle, collect, dry=False, corpus_loaded
|
|
|
339
339
|
if isinstance(lid, str):
|
|
340
340
|
local_ids.add(lid)
|
|
341
341
|
|
|
342
|
-
# Metadata SELECTS candidates; presence in the deployed
|
|
342
|
+
# Metadata SELECTS candidates; presence in the deployed instructions AUTHORIZES the
|
|
343
343
|
# delete (contract v2 §4). Audience metadata is a build-time projection: it
|
|
344
344
|
# cannot see that this user is on a package or version whose bundle never
|
|
345
345
|
# received the promoted bullet, and acting on it alone loses the learning.
|
|
@@ -359,7 +359,7 @@ def migrate(home, host, promotions, in_bundle, collect, dry=False, corpus_loaded
|
|
|
359
359
|
kept_not_in_bundle += 1 # promoted but not in THIS user's audience
|
|
360
360
|
continue
|
|
361
361
|
if not placed_here(home, p.get("anchor"), collect):
|
|
362
|
-
kept_not_placed += 1 # audience says yes, the
|
|
362
|
+
kept_not_placed += 1 # audience says yes, the instructions does not have it
|
|
363
363
|
continue
|
|
364
364
|
remove_ids.add(lid)
|
|
365
365
|
|
|
@@ -424,10 +424,10 @@ def main():
|
|
|
424
424
|
collect = load_collect()
|
|
425
425
|
home = collect.resolve_home(args.host, args.config_dir)
|
|
426
426
|
|
|
427
|
-
# F2 gate: only prune where the shared
|
|
427
|
+
# F2 gate: only prune where the shared instructions are actually loaded. Codex always
|
|
428
428
|
# loads AGENTS.md's central region; claude loads central only via the entry
|
|
429
429
|
# import (or inline in a full install).
|
|
430
|
-
|
|
430
|
+
instructions_loaded = True if args.host == "codex" else claude_instructions_loaded(home)
|
|
431
431
|
|
|
432
432
|
if args.domains is not None:
|
|
433
433
|
selection = [d for d in args.domains.split(",") if d]
|
|
@@ -439,7 +439,7 @@ def main():
|
|
|
439
439
|
in_bundle = make_in_bundle(selection)
|
|
440
440
|
|
|
441
441
|
s = migrate(home, args.host, promotions, in_bundle, collect,
|
|
442
|
-
dry=args.dry_run,
|
|
442
|
+
dry=args.dry_run, instructions_loaded=instructions_loaded)
|
|
443
443
|
tag = "[dry] " if args.dry_run else ""
|
|
444
444
|
if s.get("skipped"):
|
|
445
445
|
print(f"migrate-learnings: {tag}host={args.host} skipped ({s['skipped']}) — "
|
|
@@ -473,16 +473,16 @@ def _self_test():
|
|
|
473
473
|
L = {"core": "0f8c1c2a-4d1e-4abc-9def-0000000000a1",
|
|
474
474
|
"bb": "0f8c1c2a-4d1e-4abc-9def-0000000000b2",
|
|
475
475
|
"off": "0f8c1c2a-4d1e-4abc-9def-0000000000c3"}
|
|
476
|
-
A = {"core": "universal
|
|
477
|
-
"off": "office
|
|
476
|
+
A = {"core": "universal instructions rule", "bb": "builder instructions rule",
|
|
477
|
+
"off": "office instructions rule"}
|
|
478
478
|
promos = [{"learning_id": L["core"], "anchor": A["core"], "tier": "core", "domains": []},
|
|
479
479
|
{"learning_id": L["bb"], "anchor": A["bb"], "tier": "domain", "domains": ["builder-base"]},
|
|
480
480
|
{"learning_id": L["off"], "anchor": A["off"], "tier": "domain", "domains": ["office-work"]}]
|
|
481
481
|
|
|
482
482
|
def seed_claude(placed=("core", "bb", "off")):
|
|
483
|
-
"""`placed` = which promoted anchors this user's DEPLOYED
|
|
483
|
+
"""`placed` = which promoted anchors this user's DEPLOYED instructions actually
|
|
484
484
|
carries. Deletion is authorized by that, not by the audience metadata, so
|
|
485
|
-
a fixture without
|
|
485
|
+
a fixture without an instruction would let a metadata-only bug pass."""
|
|
486
486
|
home = pathlib.Path(tempfile.mkdtemp(prefix="migrate-selftest-"))
|
|
487
487
|
(home / "personal").mkdir(parents=True)
|
|
488
488
|
(home / "central").mkdir(parents=True)
|
|
@@ -524,13 +524,13 @@ def _self_test():
|
|
|
524
524
|
checks.append(("idempotent re-run", s2["removed"] == 0))
|
|
525
525
|
|
|
526
526
|
# 1b) CONTRAST CONTROL for the v2 authorization. Same audience metadata as
|
|
527
|
-
# above — builder-base IS selected — but this user's deployed
|
|
527
|
+
# above — builder-base IS selected — but this user's deployed instructions does
|
|
528
528
|
# NOT carry the bullet (a package/version whose bundle never got it). The
|
|
529
529
|
# metadata-only rule deletes here and loses the learning; presence keeps.
|
|
530
530
|
# If placed_here() ever returns True unconditionally, this check fails.
|
|
531
531
|
home = seed_claude(placed=("core",))
|
|
532
532
|
s = migrate(home, "claude", promos, make_in_bundle(["builder-base"]), collect)
|
|
533
|
-
checks.append(("audience says yes but
|
|
533
|
+
checks.append(("audience says yes but instructions lacks it -> KEEP",
|
|
534
534
|
s["removed"] == 1 and s["kept_not_placed"] == 1
|
|
535
535
|
and L["bb"] in local_ids(home) and md_has(home, L["bb"])))
|
|
536
536
|
|
|
@@ -578,13 +578,13 @@ def _self_test():
|
|
|
578
578
|
s["prose_removed"] == 1 and L["bb"] not in agents_txt))
|
|
579
579
|
|
|
580
580
|
# 5) F2 gate: a packaged claude entry lacking @central/bundle.md means the
|
|
581
|
-
#
|
|
581
|
+
# instructions are NOT loaded -> keep everything (never orphan a personal copy).
|
|
582
582
|
home = seed_claude() # apply_claude writes an entry WITHOUT @central/bundle.md
|
|
583
|
-
checks.append(("F2: unwired packaged entry ->
|
|
584
|
-
|
|
583
|
+
checks.append(("F2: unwired packaged entry -> instructions not loaded",
|
|
584
|
+
claude_instructions_loaded(home) is False))
|
|
585
585
|
s = migrate(home, "claude", promos, make_in_bundle(["builder-base"]),
|
|
586
|
-
collect,
|
|
587
|
-
checks.append(("F2:
|
|
586
|
+
collect, instructions_loaded=False)
|
|
587
|
+
checks.append(("F2: instructions-not-loaded keeps ALL",
|
|
588
588
|
s.get("skipped") == "corpus-not-loaded"
|
|
589
589
|
and local_ids(home) == {L["core"], L["bb"], L["off"]}))
|
|
590
590
|
entry = home / "CLAUDE.md"
|
|
@@ -593,24 +593,24 @@ def _self_test():
|
|
|
593
593
|
# harness declined, which is what the canary exists to detect, so the authorization is its
|
|
594
594
|
# recorded proof — and the proof is bound to a rev, so a reassembly does not inherit it.
|
|
595
595
|
checks.append(("F2: wired entry, no activation proof -> KEEP",
|
|
596
|
-
|
|
596
|
+
claude_instructions_loaded(home, state_dir=home / "state") is False))
|
|
597
597
|
bundle = home / "central" / "bundle.md"
|
|
598
598
|
bundle.write_text(bundle.read_text(encoding="utf-8") + "\nagent-bios-bundle-rev: deadbeef\n",
|
|
599
599
|
encoding="utf-8")
|
|
600
600
|
state = home / "state"
|
|
601
601
|
state.mkdir(parents=True, exist_ok=True)
|
|
602
602
|
(state / "activation.txt").write_text("agent-bios-bundle-rev: deadbeef\n", encoding="utf-8")
|
|
603
|
-
checks.append(("F2: wired entry + matching proof ->
|
|
604
|
-
|
|
603
|
+
checks.append(("F2: wired entry + matching proof -> instructions loaded",
|
|
604
|
+
claude_instructions_loaded(home, state_dir=state) is True))
|
|
605
605
|
(state / "activation.txt").write_text("agent-bios-bundle-rev: 00000000\n", encoding="utf-8")
|
|
606
606
|
checks.append(("F2: proof for a different rev -> KEEP",
|
|
607
|
-
|
|
607
|
+
claude_instructions_loaded(home, state_dir=state) is False))
|
|
608
608
|
# CONTRAST CONTROL for the substring hole: the import string inside a fenced block is not an
|
|
609
609
|
# import, and before the proof requirement this alone authorized the delete.
|
|
610
610
|
fenced = pathlib.Path(tempfile.mkdtemp(prefix="migrate-fenced-"))
|
|
611
611
|
(fenced / "CLAUDE.md").write_text("# CLAUDE.md\n```\n@central/bundle.md\n```\n", encoding="utf-8")
|
|
612
612
|
checks.append(("F2: import string with no activation proof -> KEEP",
|
|
613
|
-
|
|
613
|
+
claude_instructions_loaded(fenced, state_dir=fenced) is False))
|
|
614
614
|
# …and the same file WITH a matching proof, which is the case the line above cannot
|
|
615
615
|
# separate: it passes whether the import test is honest or not, because the missing
|
|
616
616
|
# proof decides it either way. The proof is bound to the bundle's rev and not to this
|
|
@@ -621,13 +621,13 @@ def _self_test():
|
|
|
621
621
|
"# bundle\nagent-bios-bundle-rev: deadbeef\n", encoding="utf-8")
|
|
622
622
|
(fenced / "activation.txt").write_text("agent-bios-bundle-rev: deadbeef\n", encoding="utf-8")
|
|
623
623
|
checks.append(("F2: FENCED import + matching proof -> still KEEP",
|
|
624
|
-
|
|
624
|
+
claude_instructions_loaded(fenced, state_dir=fenced) is False))
|
|
625
625
|
(fenced / "CLAUDE.md").write_text("# CLAUDE.md\n@central/bundle.md\n", encoding="utf-8")
|
|
626
626
|
checks.append(("F2: the same proof with a REAL import -> loaded",
|
|
627
|
-
|
|
627
|
+
claude_instructions_loaded(fenced, state_dir=fenced) is True))
|
|
628
628
|
|
|
629
629
|
# placed_here verifies a whole-file placement as a FILE and a bullet anchor as TEXT.
|
|
630
|
-
# They used to be OR'd, so any
|
|
630
|
+
# They used to be OR'd, so any instructions document that merely NAMED a guide authorized
|
|
631
631
|
# deleting the personal copy of a learning placed in it — and the live manifest's one
|
|
632
632
|
# anchor is `tooling-gotchas.md`, which the entry file names in prose.
|
|
633
633
|
mention = pathlib.Path(tempfile.mkdtemp(prefix="migrate-anchor-"))
|
|
@@ -637,13 +637,13 @@ def _self_test():
|
|
|
637
637
|
encoding="utf-8")
|
|
638
638
|
checks.append(("anchor: a named-but-absent guide is NOT placed",
|
|
639
639
|
placed_here(mention, "tooling-gotchas.md") is False))
|
|
640
|
-
checks.append(("anchor: a phrase anchor still matches
|
|
640
|
+
checks.append(("anchor: a phrase anchor still matches instructions TEXT",
|
|
641
641
|
placed_here(mention, "the bullet text itself") is True))
|
|
642
642
|
(mention / "guides" / "tooling-gotchas.md").write_text("# guide\n", encoding="utf-8")
|
|
643
643
|
checks.append(("anchor: the deployed guide file IS placed",
|
|
644
644
|
placed_here(mention, "tooling-gotchas.md") is True))
|
|
645
645
|
# (The old "full install is always loaded" case is gone with full mode: there is no shape
|
|
646
|
-
# whose
|
|
646
|
+
# whose instructions loads without the entry import, so nothing is exempt from the proof.)
|
|
647
647
|
|
|
648
648
|
# 6) F5: the TRAILING comment's id wins; a learning_id quoted in the lesson
|
|
649
649
|
# body must never shadow it (else a jsonl/prose desync).
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-bios",
|
|
3
|
-
"version": "0.19.
|
|
4
|
-
"releaseDate": "2026-09-
|
|
5
|
-
"description": "A thin, low-level instruction layer for LLM CLI agents: one set of principles and behavior whichever model you run. Stores
|
|
3
|
+
"version": "0.19.2",
|
|
4
|
+
"releaseDate": "2026-09-14",
|
|
5
|
+
"description": "A thin, low-level instruction layer for LLM CLI agents: one set of principles and behavior whichever model you run. Stores private, editable instructions for explicitly activated sessions.",
|
|
6
6
|
"bin": {
|
|
7
7
|
"agent-bios": "install.sh"
|
|
8
8
|
},
|
|
@@ -30,26 +30,42 @@
|
|
|
30
30
|
"compose/assemble.py",
|
|
31
31
|
"compose/prune-backups.py",
|
|
32
32
|
"compose/check-domains.py",
|
|
33
|
-
"compose/
|
|
33
|
+
"compose/instructions-state.py",
|
|
34
34
|
"compose/write-update-cache.py",
|
|
35
35
|
"compose/canary.sh",
|
|
36
|
+
"compose/corpus-state.py",
|
|
36
37
|
"compose/corpus.py",
|
|
37
|
-
"compose/
|
|
38
|
-
"compose/corpus_store.py",
|
|
38
|
+
"compose/corpus_app.py",
|
|
39
39
|
"compose/corpus_catalog.py",
|
|
40
|
-
"compose/
|
|
40
|
+
"compose/corpus_import.py",
|
|
41
41
|
"compose/corpus_install.py",
|
|
42
|
+
"compose/corpus_session.py",
|
|
42
43
|
"compose/corpus_setup.py",
|
|
43
44
|
"compose/corpus_setup_cli.py",
|
|
44
45
|
"compose/corpus_setup_i18n.py",
|
|
45
46
|
"compose/corpus_setup_ui.py",
|
|
47
|
+
"compose/corpus_store.py",
|
|
48
|
+
"compose/corpus_transaction.py",
|
|
49
|
+
"compose/corpus_ui.py",
|
|
46
50
|
"compose/corpus_ui_runtime.py",
|
|
51
|
+
"compose/corpus_understand.py",
|
|
52
|
+
"compose/instructions.py",
|
|
53
|
+
"compose/instructions_ui.py",
|
|
54
|
+
"compose/instructions_store.py",
|
|
55
|
+
"compose/instructions_catalog.py",
|
|
56
|
+
"compose/instructions_session.py",
|
|
57
|
+
"compose/instructions_install.py",
|
|
58
|
+
"compose/instructions_setup.py",
|
|
59
|
+
"compose/instructions_setup_cli.py",
|
|
60
|
+
"compose/instructions_setup_i18n.py",
|
|
61
|
+
"compose/instructions_setup_ui.py",
|
|
62
|
+
"compose/instructions_ui_runtime.py",
|
|
47
63
|
"compose/ui_runtime/",
|
|
48
|
-
"compose/
|
|
49
|
-
"compose/
|
|
64
|
+
"compose/instructions_import.py",
|
|
65
|
+
"compose/instructions_app.py",
|
|
50
66
|
"compose/app_bridge/",
|
|
51
|
-
"compose/
|
|
52
|
-
"compose/
|
|
67
|
+
"compose/instructions_transaction.py",
|
|
68
|
+
"compose/instructions_understand.py",
|
|
53
69
|
"compose/bootstrap/",
|
|
54
70
|
"compose/setup/START.md",
|
|
55
71
|
"launch/check-prompting-targets.sh",
|
package/provenance.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"commit":"
|
|
1
|
+
{"commit":"172928b728c7048ef77b810da61261594ddd75aa","committedAt":"2026-09-14T01:42:28+09:00","dirty":false}
|
|
File without changes
|