@codedrifters/configulator 0.0.259 → 0.0.261

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/lib/index.mjs CHANGED
@@ -4445,7 +4445,7 @@ var jestBundle = {
4445
4445
  // src/agent/bundles/maintenance-audit.ts
4446
4446
  var maintenanceAuditSubAgent = {
4447
4447
  name: "maintenance-audit",
4448
- description: "Audits documentation registries and cross-references for integrity (broken links, registry drift, stale indexes) and applies idempotent fixes. One phase per session, tracked by maint:* GitHub issue labels with filesystem-based durability between phases.",
4448
+ description: "Audits documentation registries and cross-references for integrity (broken links, registry drift, stale indexes), applies idempotent fixes, then re-runs the checks to confirm the fixes cleared the reported findings. One phase per session, tracked by maint:* GitHub issue labels with filesystem-based durability between phases.",
4449
4449
  model: AGENT_MODEL.POWERFUL,
4450
4450
  maxTurns: 80,
4451
4451
  platforms: { cursor: { exclude: true } },
@@ -4503,18 +4503,18 @@ var maintenanceAuditSubAgent = {
4503
4503
  "",
4504
4504
  "## State Machine Overview",
4505
4505
  "",
4506
- "Maintenance audits flow through **2 phases**:",
4506
+ "Maintenance audits flow through **3 phases**:",
4507
4507
  "",
4508
4508
  "```",
4509
- "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
4510
- "\u2502 1. SCAN \u2502\u2500\u2500\u2500\u2500\u25B6\u2502 2. FIX \u2502",
4511
- "\u2502 Walk doc \u2502 \u2502 Read audit \u2502",
4512
- "\u2502 tree, check \u2502 \u2502 report, \u2502",
4513
- "\u2502 xrefs and \u2502 \u2502 apply safe \u2502",
4514
- "\u2502 indexes, \u2502 \u2502 idempotent \u2502",
4515
- "\u2502 write audit \u2502 \u2502 fixes, then \u2502",
4516
- "\u2502 report \u2502 \u2502 verify \u2502",
4517
- "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518",
4509
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510 \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
4510
+ "\u2502 1. SCAN \u2502\u2500\u2500\u2500\u2500\u25B6\u2502 2. FIX \u2502\u2500\u2500\u2500\u2500\u25B6\u2502 3. VERIFY \u2502",
4511
+ "\u2502 Walk doc \u2502 \u2502 Read audit \u2502 \u2502 Re-run the \u2502",
4512
+ "\u2502 tree, check \u2502 \u2502 report, \u2502 \u2502 scan checks \u2502",
4513
+ "\u2502 xrefs and \u2502 \u2502 apply safe \u2502 \u2502 scoped to \u2502",
4514
+ "\u2502 indexes, \u2502 \u2502 idempotent \u2502 \u2502 fixed paths,\u2502",
4515
+ "\u2502 write audit \u2502 \u2502 fixes, write\u2502 \u2502 compare pre \u2502",
4516
+ "\u2502 report \u2502 \u2502 fix report \u2502 \u2502 and post \u2502",
4517
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518",
4518
4518
  "```",
4519
4519
  "",
4520
4520
  "**Issue labels encode the phase:**",
@@ -4522,18 +4522,22 @@ var maintenanceAuditSubAgent = {
4522
4522
  "| Label | Phase | Session work |",
4523
4523
  "|-------|-------|-------------|",
4524
4524
  "| `maint:scan` | 1. Scan | Walk the configured doc tree, check cross-references and registry indexes, write a durable audit report. |",
4525
- "| `maint:fix` | 2. Fix | Read the audit report, apply idempotent fixes, then verify the fixes cleared the reported findings. |",
4525
+ "| `maint:fix` | 2. Fix | Read the audit report, apply idempotent fixes, write a durable fix report. |",
4526
+ "| `maint:verify` | 3. Verify | Re-run the same checks from the parent `maint:scan` issue scoped to the paths and registries the fix phase touched, compare pre and post findings, close the parent scan issue when clean, and file a follow-up `maint:scan` for any residual findings. |",
4526
4527
  "",
4527
4528
  "All issues also carry `type:maintenance` and a `status:*` label.",
4528
4529
  "",
4529
- "**Issue count per audit cycle:** 1 scan + 1 fix = **2 sessions**.",
4530
+ "**Issue count per audit cycle:** 1 scan + 1 fix + 1 verify = **3 sessions**.",
4530
4531
  "",
4531
4532
  "**Shortened paths:**",
4532
4533
  "- Scan finds no issues \u2192 close scan issue with a justification,",
4533
- " do not create a fix issue \u2192 **1 session**.",
4534
+ " do not create a fix or verify issue \u2192 **1 session**.",
4534
4535
  "- Every reported finding requires a human judgment call \u2192 close",
4535
4536
  " scan with the report, open a `status:needs-attention` flag,",
4536
- " do not auto-create a fix issue \u2192 **1 session**.",
4537
+ " do not auto-create a fix or verify issue \u2192 **1 session**.",
4538
+ "- Fix phase applied only `flag-for-human` decisions (no auto-",
4539
+ " fixable findings landed) \u2192 close the fix issue with the",
4540
+ " skipped list and do not create a verify issue \u2192 **2 sessions**.",
4537
4541
  "",
4538
4542
  "---",
4539
4543
  "",
@@ -4563,7 +4567,9 @@ var maintenanceAuditSubAgent = {
4563
4567
  "Run this loop exactly once per session. Never start a second issue.",
4564
4568
  "",
4565
4569
  "1. Claim one open `type:maintenance` issue using phase priority:",
4566
- " `maint:scan` > `maint:fix`.",
4570
+ " `maint:verify` > `maint:fix` > `maint:scan`. Verify ahead of fix",
4571
+ " and scan so the oldest in-flight audit cycle finishes closing",
4572
+ " the loop before a new cycle starts.",
4567
4573
  "2. Transition `status:ready` \u2192 `status:in-progress` and create the",
4568
4574
  " branch per your project's branch-naming convention.",
4569
4575
  "3. Execute the phase handler that matches the issue's `maint:*`",
@@ -4675,24 +4681,30 @@ var maintenanceAuditSubAgent = {
4675
4681
  " - **All findings need human judgment** \u2192 commit the report,",
4676
4682
  " comment on the scan issue summarizing the findings, apply",
4677
4683
  " `status:needs-attention`, and close the issue. Do not create",
4678
- " a `maint:fix` issue.",
4684
+ " a `maint:fix` or `maint:verify` issue.",
4679
4685
  " - **At least one auto-fixable finding** \u2192 create a `maint:fix`",
4680
4686
  " issue (blocked on this scan issue via `Depends on: #N`). The",
4681
- " fix issue body must reference the audit report path and",
4682
- " enumerate the auto-fix categories to apply.",
4687
+ " fix issue body must reference the audit report path, enumerate",
4688
+ " the auto-fix categories to apply, and record the parent scan",
4689
+ " issue number so Phase 3 (Verify) can close the loop.",
4683
4690
  "",
4684
- "6. **Commit and push.**",
4691
+ "6. **Commit and push.** Leave the scan issue open so the downstream",
4692
+ " `maint:verify` phase can close it (or file a follow-up scan)",
4693
+ " after Phase 2 runs.",
4685
4694
  "",
4686
4695
  "---",
4687
4696
  "",
4688
4697
  "## Phase 2: Fix (`maint:fix`)",
4689
4698
  "",
4690
- "**Goal:** Read the audit report, apply idempotent fixes, verify",
4691
- "they cleared the reported findings, and commit the doc-tree changes.",
4699
+ "**Goal:** Read the audit report, apply idempotent fixes, write a",
4700
+ "fix report, and enqueue the verify phase so the audit cycle",
4701
+ "actually closes its loop.",
4692
4702
  "",
4693
- "**Budget:** Bounded edits to files under `<DOCS_ROOT>` plus a final",
4694
- "verification re-run of the checks from Phase 1. No new audit",
4695
- "categories. No fixes that require authoring new content.",
4703
+ "**Budget:** Bounded edits to files under `<DOCS_ROOT>` and one fix",
4704
+ "report file. No new audit categories. No fixes that require",
4705
+ "authoring new content. The formal re-scan lives in Phase 3 \u2014",
4706
+ "Phase 2 confirms only that it did not regress the files it touched",
4707
+ "(a smoke check, not the full pre/post comparison).",
4696
4708
  "",
4697
4709
  "### Fix Categories",
4698
4710
  "",
@@ -4726,11 +4738,13 @@ var maintenanceAuditSubAgent = {
4726
4738
  " mark it `flag-for-human` and skip. Authoring new docs belongs",
4727
4739
  " to the writer agent for that doc type, not this agent.",
4728
4740
  "",
4729
- "5. **Verify.** Re-run the same checks the scan phase ran, scoped",
4730
- " to the files the fix phase touched (plus any index files those",
4731
- " edits affect). Every finding the fix phase claimed to resolve",
4732
- " must now be gone. Any finding that remains is a regression \u2014",
4733
- " revert the corresponding edit and mark it `flag-for-human`.",
4741
+ "5. **Smoke check the touched files.** Before writing the fix",
4742
+ " report, spot-check that the specific findings the fix phase",
4743
+ " claimed to resolve are at least no longer present in the edited",
4744
+ " file(s). This is a narrow local check \u2014 not the full re-scan,",
4745
+ " which is Phase 3's job. If a finding the fix phase targeted",
4746
+ " still reproduces in the edited file, revert that edit and mark",
4747
+ " the finding `flag-for-human` in the fix report instead.",
4734
4748
  "",
4735
4749
  "6. **Write the fix report** to:",
4736
4750
  " ```",
@@ -4761,18 +4775,141 @@ var maintenanceAuditSubAgent = {
4761
4775
  "",
4762
4776
  " ## Skipped",
4763
4777
  " <findings that were stale, flagged for human, or reverted",
4764
- " during verification \u2014 one entry each, with the reason>",
4778
+ " during the smoke check \u2014 one entry each, with the reason>",
4765
4779
  "",
4766
- " ## Verification",
4767
- " - **Re-scan result:** clean / <N> residual findings",
4768
- " - **Residual findings:** <list, with reasons \u2014 each becomes a",
4769
- " follow-up `flag-for-human` note>",
4780
+ " ## Paths Touched",
4781
+ " <ordered list of files edited, plus any index files those edits",
4782
+ " affect. This is the Phase 3 re-scan scope \u2014 the verify phase",
4783
+ " reads this section to decide which paths to re-check.>",
4770
4784
  " ```",
4771
4785
  "",
4772
4786
  "7. **Comment on the scan issue** with a summary of what was fixed,",
4773
- " what was skipped, and any residual findings.",
4787
+ " what was skipped, and that Phase 3 (Verify) will close the loop.",
4788
+ "",
4789
+ "8. **Create the `maint:verify` issue.** Block it on this fix issue",
4790
+ " via `Depends on: #N` so it only runs after the fix PR lands.",
4791
+ " The verify issue body must reference:",
4792
+ " - The parent `maint:scan` issue number",
4793
+ " - The Phase 1 audit report path",
4794
+ " - The Phase 2 fix report path",
4795
+ " - The `Paths Touched` list (so Phase 3 scopes the re-scan",
4796
+ " correctly)",
4797
+ " - The same check catalog the scan phase used",
4798
+ "",
4799
+ " If the fix phase applied **zero** auto-fixes (every finding was",
4800
+ " `stale-finding` or `flag-for-human`), skip the verify issue \u2014",
4801
+ " there is nothing to verify. Close the fix issue with a summary,",
4802
+ " comment on the scan issue, and let a human decide whether to",
4803
+ " re-scan.",
4804
+ "",
4805
+ "9. **Commit and push.**",
4774
4806
  "",
4775
- "8. **Commit and push.**",
4807
+ "---",
4808
+ "",
4809
+ "## Phase 3: Verify (`maint:verify`)",
4810
+ "",
4811
+ "**Goal:** Close the loop on the audit cycle. Re-run the same checks",
4812
+ "the scan phase ran, scoped to the paths and registries the fix",
4813
+ "phase actually touched, compare pre and post findings, and record",
4814
+ "the result in a durable verify report.",
4815
+ "",
4816
+ "**Budget:** Filesystem reads + registry parsing, just like Phase 1,",
4817
+ "but bounded to the paths enumerated in the fix report's",
4818
+ "`Paths Touched` section (plus any index files those paths transit).",
4819
+ "No edits to source docs in this phase \u2014 if the re-scan surfaces a",
4820
+ "regression, record it and file a follow-up `maint:scan` issue,",
4821
+ "but do not attempt to re-fix in-session.",
4822
+ "",
4823
+ "### Steps",
4824
+ "",
4825
+ "1. **Read the verify scope** from the issue body. Confirm the parent",
4826
+ " scan issue number, the audit report path, the fix report path,",
4827
+ " and the `Paths Touched` list. If any of these are missing or",
4828
+ " the files they reference do not exist, close the verify issue",
4829
+ " with `status:needs-attention` and stop.",
4830
+ "",
4831
+ "2. **Re-run the same checks the scan phase ran**, scoped to the",
4832
+ " paths the fix phase touched plus any index or registry files",
4833
+ " those paths transit. Use the identical check catalog that the",
4834
+ " parent scan issue declared \u2014 do not add or remove checks",
4835
+ " between scan and verify.",
4836
+ "",
4837
+ "3. **Compare pre and post findings.** For each finding in the Phase 1",
4838
+ " audit report that fell within the re-scan scope, classify it as:",
4839
+ " - **resolved** \u2014 absent from the re-scan; the fix worked.",
4840
+ " - **still-failing** \u2014 still present in the re-scan; the fix did",
4841
+ " not clear it.",
4842
+ " - **regressed** \u2014 was not in the Phase 1 audit report but appears",
4843
+ " now; the fix introduced it.",
4844
+ " - **out-of-scope** \u2014 was in the Phase 1 audit report but its",
4845
+ " path was not in the fix phase's `Paths Touched` list, so this",
4846
+ " verify pass cannot speak to it.",
4847
+ "",
4848
+ "4. **Write the verify report** to:",
4849
+ " ```",
4850
+ " <AUDIT_ROOT>/maint-verify-<AUDIT_SLUG>-<YYYY-MM-DD>.md",
4851
+ " ```",
4852
+ "",
4853
+ " Format:",
4854
+ " ```markdown",
4855
+ " ---",
4856
+ ' title: "Maintenance Verify: <AUDIT_SLUG>"',
4857
+ " date: YYYY-MM-DD",
4858
+ " parent_issue: <N>",
4859
+ " scan_issue: <N>",
4860
+ " fix_issue: <N>",
4861
+ " audit_report: <path to Phase 1 scan report>",
4862
+ " fix_report: <path to Phase 2 fix report>",
4863
+ " status: complete",
4864
+ " ---",
4865
+ "",
4866
+ " # Maintenance Verify: <AUDIT_SLUG>",
4867
+ "",
4868
+ " ## Source Reports",
4869
+ " - Scan report: <link>",
4870
+ " - Fix report: <link>",
4871
+ "",
4872
+ " ## Re-scan Scope",
4873
+ " - **Paths re-checked:** <list \u2014 from the fix report's",
4874
+ " `Paths Touched` section>",
4875
+ " - **Checks re-run:** <same catalog the scan phase used>",
4876
+ "",
4877
+ " ## Pre/Post Comparison",
4878
+ " | Status | Count | Findings |",
4879
+ " |--------|-------|----------|",
4880
+ " | resolved | N | <one line per finding: category + file:line> |",
4881
+ " | still-failing | N | <one line per finding> |",
4882
+ " | regressed | N | <one line per finding> |",
4883
+ " | out-of-scope | N | <one line per finding> |",
4884
+ "",
4885
+ " ## Verdict",
4886
+ " - **clean** \u2014 every in-scope finding resolved and no regressions;",
4887
+ " the parent scan issue will be closed.",
4888
+ " - **residual** \u2014 one or more still-failing or regressed findings;",
4889
+ " a follow-up `maint:scan` issue is filed and the parent scan",
4890
+ " issue is closed with a reference to the follow-up.",
4891
+ " ```",
4892
+ "",
4893
+ "5. **Decide the next step:**",
4894
+ " - **Clean verdict** (every in-scope finding resolved, no",
4895
+ " regressions, no still-failing entries) \u2192 comment on the parent",
4896
+ " `maint:scan` issue summarizing the result and **close it**.",
4897
+ " Do not file a follow-up scan.",
4898
+ " - **Residual verdict** (one or more `still-failing` or",
4899
+ " `regressed` entries) \u2192 file a new `maint:scan` issue for the",
4900
+ " residual scope, blocked on nothing (it is ready to run on its",
4901
+ " own schedule), and link the verify report from its body. Then",
4902
+ " comment on the parent scan issue with the residual summary and",
4903
+ " **close it**.",
4904
+ " - **Out-of-scope-only verdict** (every finding fell outside the",
4905
+ " fix phase's `Paths Touched`) \u2192 comment on the parent scan",
4906
+ " issue explaining that the fix phase did not cover those paths",
4907
+ " and leave it open with `status:needs-attention` so a human can",
4908
+ " re-scope the cycle. Do not auto-close the parent scan issue",
4909
+ " in this case.",
4910
+ "",
4911
+ "6. **Commit and push.** Close the verify issue with a one-line",
4912
+ " summary of the verdict.",
4776
4913
  "",
4777
4914
  "---",
4778
4915
  "",
@@ -4782,11 +4919,13 @@ var maintenanceAuditSubAgent = {
4782
4919
  "|-----------|-------|------|",
4783
4920
  "| Downstream (last resort) | Writer agent for the audited doc type | When the audit surfaces findings that require authoring new content (missing target, partial coverage that can only be resolved by writing a new doc), the fix phase flags them for human \u2014 the human may then dispatch the appropriate writer agent. This agent never opens writer-agent issues itself. |",
4784
4921
  "",
4785
- "**File boundaries:** Writes audit and fix reports to",
4922
+ "**File boundaries:** Writes audit, fix, and verify reports to",
4786
4923
  "`<AUDIT_ROOT>/`. Applies bounded, idempotent edits under",
4787
- "`<DOCS_ROOT>/` per the fix-policy declared in the fix issue body.",
4788
- "Never writes to source code, never writes to doc trees outside",
4789
- "`<DOCS_ROOT>`, never authors new document files to close a gap.",
4924
+ "`<DOCS_ROOT>/` only in Phase 2 (Fix), per the fix-policy declared",
4925
+ "in the fix issue body. Phase 3 (Verify) never edits doc files \u2014",
4926
+ "it only reads and re-scans. Never writes to source code, never",
4927
+ "writes to doc trees outside `<DOCS_ROOT>`, never authors new",
4928
+ "document files to close a gap.",
4790
4929
  "",
4791
4930
  "---",
4792
4931
  "",
@@ -4798,6 +4937,10 @@ var maintenanceAuditSubAgent = {
4798
4937
  "- All findings are `flag-for-human` and the fix issue has nothing",
4799
4938
  " to auto-apply \u2014 resolve by closing the fix issue with a summary",
4800
4939
  " instead",
4940
+ "- A `maint:verify` issue references a fix report whose",
4941
+ " `Paths Touched` list is empty \u2014 there is nothing to re-scan, so",
4942
+ " close the verify issue with a summary and let a human decide",
4943
+ " whether to re-run the scan",
4801
4944
  "",
4802
4945
  "---",
4803
4946
  "",
@@ -4812,13 +4955,24 @@ var maintenanceAuditSubAgent = {
4812
4955
  " Record out-of-scope observations in the report for human review.",
4813
4956
  "- **No authoring.** Do not invent new document content to close a",
4814
4957
  " finding. That work belongs to the writer agent for the doc type.",
4815
- "- **Verify before closing.** Always re-run the checks after",
4816
- " applying fixes and record the result in the fix report."
4958
+ "- **Verify closes the loop.** Every fix-phase run that lands at",
4959
+ " least one auto-fix must enqueue a `maint:verify` issue. Phase 3",
4960
+ " is the only phase that closes the parent `maint:scan` issue.",
4961
+ " Phase 2 never closes the scan issue itself.",
4962
+ "- **Pre/post comparison is required.** The verify report must",
4963
+ " classify every in-scope finding from the scan report as",
4964
+ " `resolved`, `still-failing`, `regressed`, or `out-of-scope`.",
4965
+ " An unclassified finding means the re-scan was incomplete \u2014 re-",
4966
+ " run the missing checks before writing the verdict.",
4967
+ "- **Residual findings get their own cycle.** When the verify phase",
4968
+ " finds `still-failing` or `regressed` entries, file a follow-up",
4969
+ " `maint:scan` issue rather than attempting to re-fix in-session.",
4970
+ " The new scan starts its own audit cycle with a fresh report."
4817
4971
  ].join("\n")
4818
4972
  };
4819
4973
  var maintenanceAuditSkill = {
4820
4974
  name: "audit-docs",
4821
- description: "Kick off a documentation-maintenance audit cycle (scan \u2192 fix). Creates a maint:scan issue for the supplied scope and dispatches Phase 1.",
4975
+ description: "Kick off a documentation-maintenance audit cycle (scan \u2192 fix \u2192 verify). Creates a maint:scan issue for the supplied scope and dispatches Phase 1.",
4822
4976
  disableModelInvocation: true,
4823
4977
  userInvocable: true,
4824
4978
  context: "fork",
@@ -4830,7 +4984,8 @@ var maintenanceAuditSkill = {
4830
4984
  "Kick off a maintenance-audit cycle against a configurable doc",
4831
4985
  "tree. Creates a `maint:scan` issue targeted at the requested",
4832
4986
  "scope and dispatches Phase 1 (Scan) in the maintenance-audit",
4833
- "agent.",
4987
+ "agent. Subsequent phases (`maint:fix`, `maint:verify`) are",
4988
+ "created automatically as the cycle progresses.",
4834
4989
  "",
4835
4990
  "## Usage",
4836
4991
  "",
@@ -4857,30 +5012,102 @@ var maintenanceAuditSkill = {
4857
5012
  "2. Execute Phase 1 (Scan) of the maintenance-audit agent.",
4858
5013
  "3. If auto-fixable findings exist, a `maint:fix` issue is created",
4859
5014
  " automatically.",
5015
+ "4. When the fix phase lands, a `maint:verify` issue is created",
5016
+ " automatically so Phase 3 can re-run the checks and close the",
5017
+ " parent scan issue.",
4860
5018
  "",
4861
5019
  "## Output",
4862
5020
  "",
4863
5021
  "- A `maint-audit-<slug>-<YYYY-MM-DD>.md` report under",
4864
5022
  " `<AUDIT_ROOT>`.",
4865
- "- A `maint:fix` issue if auto-fixable findings were found."
5023
+ "- A `maint:fix` issue if auto-fixable findings were found.",
5024
+ "- A `maint:verify` issue after the fix phase lands (Phase 3",
5025
+ " produces a `maint-verify-<slug>-<YYYY-MM-DD>.md` report)."
5026
+ ].join("\n")
5027
+ };
5028
+ var maintenanceVerifySkill = {
5029
+ name: "verify-audit",
5030
+ description: "Kick off the verify phase of a documentation-maintenance audit cycle. Creates a maint:verify issue that re-runs the scan checks scoped to the paths a fix phase touched, compares pre/post findings, and closes the parent maint:scan issue when clean or files a follow-up maint:scan for residual findings.",
5031
+ disableModelInvocation: true,
5032
+ userInvocable: true,
5033
+ context: "fork",
5034
+ agent: "maintenance-audit",
5035
+ platforms: { cursor: { exclude: true } },
5036
+ instructions: [
5037
+ "# Verify Audit",
5038
+ "",
5039
+ "Close the loop on a maintenance-audit cycle. Creates a",
5040
+ "`maint:verify` issue and dispatches Phase 3 (Verify) in the",
5041
+ "maintenance-audit agent.",
5042
+ "",
5043
+ "Phase 3 re-runs the same checks the scan phase ran, scoped to the",
5044
+ "paths the fix phase actually touched, compares pre and post",
5045
+ "findings, and writes a verify report. Based on the verdict the",
5046
+ "phase either closes the parent `maint:scan` issue or files a",
5047
+ "follow-up `maint:scan` for residual findings.",
5048
+ "",
5049
+ "## Usage",
5050
+ "",
5051
+ "/verify-audit <scan-issue-number>",
5052
+ "",
5053
+ "Where `<scan-issue-number>` is the `maint:scan` issue that kicked",
5054
+ "off the audit cycle. The skill resolves the scan report, the",
5055
+ "Phase 2 fix report, and the `Paths Touched` list from that scan",
5056
+ "issue's downstream `maint:fix` issue.",
5057
+ "",
5058
+ "Most cycles do not need this skill \u2014 Phase 2 (Fix) creates the",
5059
+ "verify issue automatically. Use this skill when:",
5060
+ "- Phase 2 ran on an older audit cycle that predates the verify",
5061
+ " phase and never enqueued a verify issue, or",
5062
+ "- A human wants to re-run the verify phase after a manual fix",
5063
+ " applied on top of the Phase 2 PR.",
5064
+ "",
5065
+ "## Steps",
5066
+ "",
5067
+ "1. Create a `maint:verify` issue with `type:maintenance`,",
5068
+ " `priority:medium`, and `status:ready`. Body must list:",
5069
+ " - The parent `maint:scan` issue number",
5070
+ " - The Phase 1 audit report path",
5071
+ " - The Phase 2 fix report path (if one exists)",
5072
+ " - The `Paths Touched` list (copied from the fix report)",
5073
+ " - The audit check catalog (copied from the scan issue)",
5074
+ "2. Execute Phase 3 (Verify) of the maintenance-audit agent.",
5075
+ "",
5076
+ "## Output",
5077
+ "",
5078
+ "- A `maint-verify-<slug>-<YYYY-MM-DD>.md` report under",
5079
+ " `<AUDIT_ROOT>` containing the pre/post comparison.",
5080
+ "- The parent `maint:scan` issue is closed (clean verdict) or a",
5081
+ " follow-up `maint:scan` issue is filed (residual verdict)."
4866
5082
  ].join("\n")
4867
5083
  };
4868
5084
  var maintenanceAuditBundle = {
4869
5085
  name: "maintenance-audit",
4870
- description: "Documentation-maintenance agent bundle. 2-phase pipeline (scan, fix) with maint:* phase labels for auditing registries and cross-references and applying idempotent fixes. Enabled by default.",
5086
+ description: "Documentation-maintenance agent bundle. 3-phase pipeline (scan, fix, verify) with maint:* phase labels for auditing registries and cross-references, applying idempotent fixes, and confirming the fixes cleared the originally-flagged findings. Enabled by default.",
4871
5087
  appliesWhen: () => true,
4872
5088
  rules: [
4873
5089
  {
4874
5090
  name: "maintenance-audit-workflow",
4875
- description: "Describes the 2-phase documentation-maintenance pipeline, the maint:* label taxonomy, and the audit-before-fix boundary.",
5091
+ description: "Describes the 3-phase documentation-maintenance pipeline, the maint:* label taxonomy, the audit-before-fix boundary, and the verify-closes-the-loop rule.",
4876
5092
  scope: AGENT_RULE_SCOPE.ALWAYS,
4877
5093
  content: [
4878
5094
  "# Maintenance Audit Workflow",
4879
5095
  "",
4880
5096
  "Use `/audit-docs <scope>` to kick off a documentation-maintenance",
4881
- "audit cycle. The pipeline runs in 2 phases \u2014 scan and fix \u2014 each",
4882
- "tracked by its own GitHub issue labeled `maint:scan` or",
4883
- "`maint:fix`. All issues carry `type:maintenance`.",
5097
+ "audit cycle. The pipeline runs in 3 phases \u2014 scan, fix, and",
5098
+ "verify \u2014 each tracked by its own GitHub issue labeled",
5099
+ "`maint:scan`, `maint:fix`, or `maint:verify`. All issues carry",
5100
+ "`type:maintenance`.",
5101
+ "",
5102
+ "One additional user-invocable skill drives the verify phase",
5103
+ "on demand:",
5104
+ "",
5105
+ "- `/verify-audit <scan-issue-number>` \u2014 re-run the scan checks",
5106
+ " scoped to the paths the fix phase touched, compare pre/post",
5107
+ " findings, and close the parent `maint:scan` issue (or file a",
5108
+ " follow-up for residual findings). Phase 2 (Fix) normally",
5109
+ " enqueues the verify issue automatically \u2014 this skill is the",
5110
+ " explicit entry point for re-running the phase on demand.",
4884
5111
  "",
4885
5112
  "The maintenance-audit agent *audits doc registries and applies",
4886
5113
  "idempotent fixes*; it does **not** author new document content.",
@@ -4896,7 +5123,7 @@ var maintenanceAuditBundle = {
4896
5123
  tags: ["workflow"]
4897
5124
  }
4898
5125
  ],
4899
- skills: [maintenanceAuditSkill],
5126
+ skills: [maintenanceAuditSkill, maintenanceVerifySkill],
4900
5127
  subAgents: [maintenanceAuditSubAgent],
4901
5128
  labels: [
4902
5129
  {
@@ -4913,6 +5140,11 @@ var maintenanceAuditBundle = {
4913
5140
  name: "maint:fix",
4914
5141
  color: "BFDADC",
4915
5142
  description: "Phase 2: apply idempotent fixes from a maintenance audit report"
5143
+ },
5144
+ {
5145
+ name: "maint:verify",
5146
+ color: "D4C5F9",
5147
+ description: "Phase 3: re-run the scan checks scoped to the paths the fix phase touched, compare pre/post findings, and close or re-queue the parent scan"
4916
5148
  }
4917
5149
  ]
4918
5150
  };
@@ -6173,7 +6405,7 @@ var orchestratorBundle = {
6173
6405
  // src/agent/bundles/people-profile.ts
6174
6406
  var peopleProfileAnalystSubAgent = {
6175
6407
  name: "people-profile-analyst",
6176
- description: "Researches an individual person (colleague, customer contact, vendor contact, partner contact, industry expert, or connector) from public sources and produces a structured markdown profile cross-linked to companies, software, and meeting notes, then enqueues downstream `company:research` and `software:research` issues for unprofiled companies and software products surfaced during profiling. One person per session, tracked by people:* GitHub issue labels.",
6408
+ description: "Researches an individual person (colleague, customer contact, vendor contact, partner contact, industry expert, or connector) from public sources and produces a structured markdown profile cross-linked to companies, software, and meeting notes, then enqueues downstream `company:research` and `software:research` issues for unprofiled companies and software products surfaced during profiling. Also handles maintenance refreshes on a configurable staleness cadence (`people:refresh`). One person per session, tracked by people:* GitHub issue labels.",
6177
6409
  model: AGENT_MODEL.POWERFUL,
6178
6410
  maxTurns: 80,
6179
6411
  platforms: { cursor: { exclude: true } },
@@ -6233,6 +6465,12 @@ var peopleProfileAnalystSubAgent = {
6233
6465
  " the `software-profile` bundle via `software:research` issues.",
6234
6466
  " Meeting notes remain link-only \u2014 this agent never creates",
6235
6467
  " meeting-research issues.",
6468
+ "9. **Refresh is targeted re-verification, not re-research.**",
6469
+ " `people:refresh` runs a small number of targeted searches focused",
6470
+ " on the narrow set of facts that drift (role, employer, primary",
6471
+ " public channel) and updates the profile in place. It never",
6472
+ " re-runs the full research-phase sweep and never forks the profile",
6473
+ " under a new slug.",
6236
6474
  "",
6237
6475
  "---",
6238
6476
  "",
@@ -6267,6 +6505,15 @@ var peopleProfileAnalystSubAgent = {
6267
6505
  "\u2502 bounded notes \u2502 \u2502 the configured path \u2502 \u2502 company/software \u2502",
6268
6506
  "\u2502 file \u2502 \u2502 \u2502 \u2502 research issues \u2502",
6269
6507
  "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518 \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518",
6508
+ "",
6509
+ "\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510",
6510
+ "\u2502 4. REFRESH \u2502 (cadence-driven, or on-demand)",
6511
+ "\u2502 Re-verify an \u2502",
6512
+ "\u2502 existing profile \u2502",
6513
+ "\u2502 with targeted web \u2502",
6514
+ "\u2502 searches. Update \u2502",
6515
+ "\u2502 in place. \u2502",
6516
+ "\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518",
6270
6517
  "```",
6271
6518
  "",
6272
6519
  "**Issue labels encode the phase:**",
@@ -6276,13 +6523,13 @@ var peopleProfileAnalystSubAgent = {
6276
6523
  "| `people:research` | 1. Research | Gather public sources. Write a bounded research-notes file. Create the draft issue. |",
6277
6524
  "| `people:draft` | 2. Draft | Read the research notes. Write the structured profile to `<PROFILES_DIR>`. Create the followup issue if warranted. |",
6278
6525
  "| `people:followup` | 3. Followup | Read the profile. Update cross-references to existing companies, software, and meeting notes. Enqueue `company:research` and `software:research` issues for unprofiled, genuinely-relevant entities surfaced in the profile. |",
6526
+ "| `people:refresh` | 4. Refresh | Read an existing profile. Run 3\u20135 targeted web searches for role, employer, and primary public channel changes. Update the profile in place and add a revision-history entry. |",
6279
6527
  "",
6280
6528
  "All issues also carry `type:people-profile` and a `status:*` label.",
6281
6529
  "",
6282
6530
  "**Issue count per person cycle:** 1 research + 1 draft + 0\u20131 followup =",
6283
- "**2\u20133 sessions**. The followup phase is skipped when the profile did",
6284
- "not surface any cross-references worth linking and no companies or",
6285
- "software products warrant downstream research.",
6531
+ "**2\u20133 sessions** on the initial cycle. `people:refresh` is an",
6532
+ "independent downstream cycle that runs on its own cadence.",
6286
6533
  "",
6287
6534
  "**Shortened paths:**",
6288
6535
  "- Research phase determines the person is out of scope (not",
@@ -6290,14 +6537,17 @@ var peopleProfileAnalystSubAgent = {
6290
6537
  " with a justification and no downstream issues are created \u2192 **1 session**.",
6291
6538
  "- Short profile with no cross-references and no downstream",
6292
6539
  " candidates \u2192 **2 sessions**.",
6540
+ "- Refresh that finds no material change \u2192 **1 session** (revision-",
6541
+ " history entry only, profile body unchanged).",
6293
6542
  "",
6294
6543
  "---",
6295
6544
  "",
6296
6545
  "## Configurable Paths",
6297
6546
  "",
6298
6547
  "The pipeline uses these placeholders. Consuming projects override the",
6299
- "defaults by passing paths in the `/profile-person` skill invocation",
6300
- "or by extending this rule in their own `agentConfig.rules`.",
6548
+ "defaults by passing paths in the `/profile-person` or `/refresh-person`",
6549
+ "skill invocations, or by extending this rule in their own",
6550
+ "`agentConfig.rules`.",
6301
6551
  "",
6302
6552
  "| Placeholder | Meaning | Default |",
6303
6553
  "|-------------|---------|---------|",
@@ -6319,26 +6569,37 @@ var peopleProfileAnalystSubAgent = {
6319
6569
  "## Refresh Cadence",
6320
6570
  "",
6321
6571
  "Profiles go stale. A person changes jobs, publishes new work, or",
6322
- "shifts focus. The pipeline supports a configurable refresh cadence:",
6572
+ "shifts focus. The pipeline supports a configurable refresh cadence",
6573
+ "so `people:refresh` issues can be filed on a schedule without",
6574
+ "hardcoding the interval:",
6323
6575
  "",
6324
- "- **Default cadence:** 180 days from the profile's `date` frontmatter.",
6325
- "- **Override:** the invoking issue body may specify a `refresh_days: N`",
6326
- " field, or the consuming project may set a project-wide default in",
6327
- " `docs/src/content/docs/project-context.md`.",
6576
+ "- **Default staleness threshold:** 180 days from the profile's",
6577
+ " `date` frontmatter.",
6578
+ "- **Override precedence** (first match wins):",
6579
+ " 1. `refresh_days` in the issue body (per-run override)",
6580
+ " 2. `refresh_days` frontmatter on the profile itself",
6581
+ " 3. Project-wide default declared under a `## Refresh Cadence`",
6582
+ " section in `docs/src/content/docs/project-context.md`",
6583
+ " 4. Built-in default: **180 days**",
6328
6584
  "",
6329
- "When the `/profile-person` skill is invoked for a slug that already",
6330
- "has a profile:",
6585
+ "When the `/refresh-person` skill is invoked for an existing profile:",
6331
6586
  "",
6332
- "- If the profile is **younger** than the refresh cadence, the skill",
6333
- " exits with a message pointing to the existing profile. Pass",
6587
+ "- If the profile is **younger** than the staleness threshold, the",
6588
+ " skill exits with a message pointing to the existing profile. Pass",
6334
6589
  " `force: true` in the issue body to refresh anyway.",
6335
- "- If the profile is **older** than the refresh cadence, the pipeline",
6336
- " proceeds in update-in-place mode: Phase 2 edits the existing file,",
6337
- " preserves its slug, and bumps the `date` frontmatter.",
6590
+ "- If the profile is **older** than the staleness threshold, the",
6591
+ " pipeline files a `people:refresh` issue and Phase 4 updates the",
6592
+ " existing file in place, preserving its slug and bumping the",
6593
+ " `date` frontmatter.",
6594
+ "",
6595
+ "The same precedence and `force: true` semantics apply when",
6596
+ "`/profile-person` is invoked for a slug that already has a profile:",
6597
+ "a fresh profile short-circuits; a stale profile is updated in place",
6598
+ "by Phase 2 rather than forked under a new slug.",
6338
6599
  "",
6339
6600
  "Refresh mode never changes the profile's role without an explicit",
6340
- "override in the refresh request \u2014 role changes are material and",
6341
- "warrant a human review step.",
6601
+ "override in the refresh request (`retype: <role>`) \u2014 role changes",
6602
+ "are material and warrant a human review step.",
6342
6603
  "",
6343
6604
  "---",
6344
6605
  "",
@@ -6347,7 +6608,8 @@ var peopleProfileAnalystSubAgent = {
6347
6608
  "Run this loop exactly once per session. Never start a second issue.",
6348
6609
  "",
6349
6610
  "1. Claim one open `type:people-profile` issue using phase priority:",
6350
- " `people:research` > `people:draft` > `people:followup`.",
6611
+ " `people:research` > `people:draft` > `people:followup` >",
6612
+ " `people:refresh`.",
6351
6613
  "2. Transition `status:ready` \u2192 `status:in-progress` and create the",
6352
6614
  " branch per your project's branch-naming convention.",
6353
6615
  "3. Execute the phase handler that matches the issue's `people:*`",
@@ -6515,6 +6777,11 @@ var peopleProfileAnalystSubAgent = {
6515
6777
  " <what the profile could not answer; flag anything the followup",
6516
6778
  " phase should cross-reference>",
6517
6779
  "",
6780
+ " ## Revision History",
6781
+ " | Date | Changes |",
6782
+ " |------|---------|",
6783
+ " | YYYY-MM-DD | Initial profile |",
6784
+ "",
6518
6785
  " ## Sources",
6519
6786
  " - <source URL> \u2014 <date accessed>",
6520
6787
  " ```",
@@ -6660,12 +6927,87 @@ var peopleProfileAnalystSubAgent = {
6660
6927
  "",
6661
6928
  "---",
6662
6929
  "",
6930
+ "## Phase 4: Refresh (`people:refresh`)",
6931
+ "",
6932
+ "**Goal:** Re-verify an existing profile against a narrow set of facts",
6933
+ "that tend to drift \u2014 current role, current employer, primary public",
6934
+ "channel (email, handle, personal site) \u2014 with a small number of",
6935
+ "targeted web searches, then update the profile in place.",
6936
+ "",
6937
+ "**Budget:** 3\u20135 targeted web searches focused on the narrow delta",
6938
+ "set. Do not redo the full research-phase sweep, do not re-gather the",
6939
+ "full background, and do not rewrite the profile body for facts that",
6940
+ "have not changed.",
6941
+ "",
6942
+ "### Steps",
6943
+ "",
6944
+ "1. **Read the existing profile** at the path referenced in the issue",
6945
+ " body. If the profile file is missing, close the issue with",
6946
+ " `status:needs-attention` and stop.",
6947
+ "",
6948
+ "2. **Confirm the staleness threshold.** Compare the profile's `date`",
6949
+ " frontmatter against today's date and the `refresh_days`",
6950
+ " frontmatter (or the project default from the Refresh Cadence",
6951
+ " section above). If the profile is younger than the threshold and",
6952
+ " the issue body does not set `force: true`, close the issue with",
6953
+ " a short comment and stop \u2014 do not burn the search budget.",
6954
+ "",
6955
+ "3. **Run 3\u20135 targeted searches.** Focus on the narrow delta set:",
6956
+ " - Current role / title at the current employer",
6957
+ " - Current employer (has the person changed jobs?)",
6958
+ " - Primary public channel (personal site URL, primary social",
6959
+ " handle, speaker inquiry form, public email if listed)",
6960
+ " - Optional: one search for notable recent public work (a new",
6961
+ " talk, post, or project) if the profile's Expertise Signals",
6962
+ " section has no entry from the last 12 months",
6963
+ "",
6964
+ "4. **Update the profile in place.** Edit only the affected sections",
6965
+ " (typically `## Current Position`, `## Contact Preferences`, and",
6966
+ " occasionally `## Expertise Signals`). Cite every new claim.",
6967
+ " Preserve the slug and the original `parent_issue` field. Bump the",
6968
+ " `date` frontmatter to today's date. Leave untouched sections",
6969
+ " untouched \u2014 refresh is a narrow delta, not a rewrite.",
6970
+ "",
6971
+ "5. **Do not silently re-type the person.** If the refresh surfaces",
6972
+ " evidence that the person's primary role has changed (e.g., a",
6973
+ " customer-contact who now works at your own organization and",
6974
+ " should become a colleague), flag it in `## Risks / Open Questions`",
6975
+ " and stop \u2014 do **not** rewrite the `role` frontmatter without an",
6976
+ " explicit override in the refresh issue body (`retype: <role>`).",
6977
+ "",
6978
+ "6. **Append a revision-history row.** Summarize the delta in one",
6979
+ " line:",
6980
+ "",
6981
+ " ```markdown",
6982
+ " | YYYY-MM-DD | Refreshed: <one-line summary of what changed> |",
6983
+ " ```",
6984
+ "",
6985
+ " When the search budget finds no material change, the row still",
6986
+ " appears so the next scheduled refresh knows this profile was",
6987
+ " reviewed:",
6988
+ "",
6989
+ " ```markdown",
6990
+ " | YYYY-MM-DD | Refreshed: no material change |",
6991
+ " ```",
6992
+ "",
6993
+ "7. **Respect privacy.** The narrow delta set is bounded to public",
6994
+ " professional facts. Never expand the refresh into private contact",
6995
+ " details, family information, or other non-professional data \u2014",
6996
+ " even if a search surfaces them. Privacy guardrails from Phase 1",
6997
+ " apply to every refresh.",
6998
+ "",
6999
+ "8. **Commit and push.** Close the refresh issue with a short comment",
7000
+ " summarizing the delta (or `no material change`).",
7001
+ "",
7002
+ "---",
7003
+ "",
6663
7004
  "## Output Boundaries",
6664
7005
  "",
6665
7006
  "This agent writes **only** to:",
6666
7007
  "",
6667
7008
  "- `<NOTES_DIR>/` \u2014 research-notes files (Phase 1)",
6668
- "- `<PROFILES_DIR>/` \u2014 person profiles (Phase 2, updated in Phase 3)",
7009
+ "- `<PROFILES_DIR>/` \u2014 person profiles (Phase 2, updated in Phases",
7010
+ " 3 and 4)",
6669
7011
  "",
6670
7012
  "In Phase 3, this agent also **creates `company:research` and",
6671
7013
  "`software:research` issues** for companies and software products",
@@ -6676,6 +7018,13 @@ var peopleProfileAnalystSubAgent = {
6676
7018
  "which pick up the issues this pipeline creates. Meeting notes",
6677
7019
  "remain link-only across all phases.",
6678
7020
  "",
7021
+ "In Phase 4, this agent only updates an existing profile in place \u2014",
7022
+ "it never forks a new profile under a different slug and never",
7023
+ "enqueues downstream `company:research` or `software:research`",
7024
+ "issues. Cross-references surfaced during a refresh are flagged in",
7025
+ "`## Risks / Open Questions` for a follow-up `people:followup` pass",
7026
+ "to handle.",
7027
+ "",
6679
7028
  "The pipeline produces **person profiles and notes only**. Deeper",
6680
7029
  "research on companies and software products is delegated to",
6681
7030
  "downstream research pipelines via `company:research` and",
@@ -6720,6 +7069,15 @@ var peopleProfileAnalystSubAgent = {
6720
7069
  " not open `type:requirement` or formal evaluation issues from this",
6721
7070
  " pipeline. Follow-up research is scoped through `company:research`",
6722
7071
  " and `software:research` only.",
7072
+ "- **Refresh respects the cadence.** Phase 4 exits early when the",
7073
+ " profile is younger than the staleness threshold and `force: true`",
7074
+ " is not set. It always appends a revision-history row so the next",
7075
+ " scheduled run knows the profile was reviewed.",
7076
+ "- **Refresh is narrow, not a rewrite.** Phase 4 re-verifies role,",
7077
+ " employer, and primary public channel with 3\u20135 targeted searches",
7078
+ " and updates only the affected sections. It never re-runs the full",
7079
+ " research-phase sweep and never rewrites sections whose underlying",
7080
+ " facts have not changed.",
6723
7081
  "- **Refresh, don't fork.** When a profile exists and is past its",
6724
7082
  " cadence, update in place rather than creating a new slug."
6725
7083
  ].join("\n")
@@ -6798,23 +7156,110 @@ var profilePersonSkill = {
6798
7156
  " other downstream artifacts itself."
6799
7157
  ].join("\n")
6800
7158
  };
7159
+ var refreshPersonSkill = {
7160
+ name: "refresh-person",
7161
+ description: "Kick off a people-profile refresh cycle. Creates a people:refresh issue for an existing profile and dispatches Phase 4 (Refresh) in the people-profile-analyst agent. Refresh re-verifies the profile's narrow delta set (role, employer, primary public channel) with 3\u20135 targeted web searches and updates it in place. Respects a configurable staleness threshold so profiles younger than the threshold exit early.",
7162
+ disableModelInvocation: true,
7163
+ userInvocable: true,
7164
+ context: "fork",
7165
+ agent: "people-profile-analyst",
7166
+ platforms: { cursor: { exclude: true } },
7167
+ instructions: [
7168
+ "# Refresh Person",
7169
+ "",
7170
+ "Re-verify an existing person profile with a small number of",
7171
+ "targeted web searches and update the profile in place. Creates a",
7172
+ "`people:refresh` issue for the target profile and dispatches",
7173
+ "Phase 4 (Refresh) in the people-profile-analyst agent.",
7174
+ "",
7175
+ "Refresh respects a configurable **staleness threshold** so scheduled",
7176
+ "refreshes do not burn search budget on profiles that are still",
7177
+ "fresh.",
7178
+ "",
7179
+ "## Usage",
7180
+ "",
7181
+ "/refresh-person <path-to-profile>",
7182
+ "",
7183
+ "Optional extensions in the issue body:",
7184
+ "- `refresh_days: <N>` \u2014 override the default 180-day staleness",
7185
+ " threshold for this run",
7186
+ "- `force: true` \u2014 refresh even if the profile is younger than the",
7187
+ " threshold",
7188
+ "- `retype: <colleague | customer-contact | vendor-contact |",
7189
+ " partner-contact | industry-expert | connector>` \u2014 explicitly",
7190
+ " allow Phase 4 to change the profile's `role` when the refresh",
7191
+ " finds material evidence of a role-type change",
7192
+ "",
7193
+ "## Staleness Threshold",
7194
+ "",
7195
+ "Order of precedence (first match wins):",
7196
+ "",
7197
+ "1. `refresh_days` in the issue body (per-run override)",
7198
+ "2. `refresh_days` frontmatter on the profile itself",
7199
+ "3. Project-wide default declared under a `## Refresh Cadence`",
7200
+ " section in `docs/src/content/docs/project-context.md`",
7201
+ "4. Built-in default: **180 days**",
7202
+ "",
7203
+ "If the profile's `date` frontmatter plus the resolved threshold is",
7204
+ "in the future (i.e. the profile is still fresh) and `force: true`",
7205
+ "is not set, Phase 4 closes the refresh issue with a short comment",
7206
+ "and stops without running any searches.",
7207
+ "",
7208
+ "## Budget",
7209
+ "",
7210
+ "- **3\u20135 targeted web searches** focused on the narrow delta set:",
7211
+ " current role / title, current employer, primary public channel",
7212
+ " (personal site, handle, speaker inquiry form, public email).",
7213
+ "- Optional: one search for notable recent public work if the",
7214
+ " profile has no Expertise Signals entry from the last 12 months.",
7215
+ "",
7216
+ "## Privacy",
7217
+ "",
7218
+ "Privacy guardrails from Phase 1 apply to every refresh. Never",
7219
+ "record private contact details, family information, or other",
7220
+ "non-professional personal data \u2014 even if a search surfaces them.",
7221
+ "",
7222
+ "## Steps",
7223
+ "",
7224
+ "1. Create a `people:refresh` issue with `type:people-profile`,",
7225
+ " `priority:medium`, and `status:ready`. Body must include the",
7226
+ " profile path and any overrides.",
7227
+ "2. Execute Phase 4 (Refresh) of the people-profile-analyst agent.",
7228
+ "",
7229
+ "## Output",
7230
+ "",
7231
+ "- The profile is updated in place (affected sections edited,",
7232
+ " `date` bumped, slug preserved)",
7233
+ "- A revision-history row summarizing the delta \u2014 or",
7234
+ " `Refreshed: no material change` when the search budget found",
7235
+ " nothing material"
7236
+ ].join("\n")
7237
+ };
6801
7238
  var peopleProfileBundle = {
6802
7239
  name: "people-profile",
6803
- description: "People research and profiling pipeline: research, draft profile, followup. Enabled by default; domain-neutral; filesystem-durable between phases. Cross-references existing companies, software, and meeting notes, and Phase 3 (Followup) hands unprofiled, genuinely-relevant companies and software products off to the `company-profile` and `software-profile` bundles via `company:research` and `software:research` issues.",
7240
+ description: "People research and profiling pipeline: research, draft profile, followup, refresh. Enabled by default; domain-neutral; filesystem-durable between phases. Cross-references existing companies, software, and meeting notes, and Phase 3 (Followup) hands unprofiled, genuinely-relevant companies and software products off to the `company-profile` and `software-profile` bundles via `company:research` and `software:research` issues. Phase 4 (Refresh) re-verifies profiles on a configurable staleness cadence.",
6804
7241
  appliesWhen: () => true,
6805
7242
  rules: [
6806
7243
  {
6807
7244
  name: "people-profile-workflow",
6808
- description: "Describes the 3-phase people-profile pipeline, the people:* label taxonomy, the cross-reference model, and the boundary against downstream research agents.",
7245
+ description: "Describes the 4-phase people-profile pipeline, the people:* label taxonomy, the cross-reference model, the refresh cadence rules, and the boundary against downstream research agents.",
6809
7246
  scope: AGENT_RULE_SCOPE.ALWAYS,
6810
7247
  content: [
6811
7248
  "# People Profile Workflow",
6812
7249
  "",
6813
7250
  "Use `/profile-person <person-name>` to kick off a person",
6814
- "research and profiling pipeline. The pipeline runs in up to 3",
6815
- "phases \u2014 research, draft, followup \u2014 each tracked by its own",
6816
- "GitHub issue labeled `people:research`, `people:draft`, or",
6817
- "`people:followup`. All issues carry `type:people-profile`.",
7251
+ "research and profiling pipeline. The pipeline runs in up to 4",
7252
+ "phases \u2014 research, draft, followup, refresh \u2014 each tracked by",
7253
+ "its own GitHub issue labeled `people:research`, `people:draft`,",
7254
+ "`people:followup`, or `people:refresh`. All issues carry",
7255
+ "`type:people-profile`.",
7256
+ "",
7257
+ "One additional user-invocable skill drives the maintenance",
7258
+ "phase independently:",
7259
+ "",
7260
+ "- `/refresh-person <path-to-profile>` \u2014 re-verify an existing",
7261
+ " profile with 3\u20135 targeted web searches and update it in",
7262
+ " place (Phase 4, respects a configurable staleness threshold).",
6818
7263
  "",
6819
7264
  "The pipeline produces **person profiles only**. Deeper research",
6820
7265
  "on companies and software products surfaced while profiling is",
@@ -6833,7 +7278,7 @@ var peopleProfileBundle = {
6833
7278
  tags: ["workflow"]
6834
7279
  }
6835
7280
  ],
6836
- skills: [profilePersonSkill],
7281
+ skills: [profilePersonSkill, refreshPersonSkill],
6837
7282
  subAgents: [peopleProfileAnalystSubAgent],
6838
7283
  labels: [
6839
7284
  {
@@ -6855,6 +7300,11 @@ var peopleProfileBundle = {
6855
7300
  name: "people:followup",
6856
7301
  color: "D4C5F9",
6857
7302
  description: "Phase 3: cross-link the profile to existing companies, software, and meeting notes, and enqueue follow-up research issues for unprofiled companies and software products"
7303
+ },
7304
+ {
7305
+ name: "people:refresh",
7306
+ color: "F9D0C4",
7307
+ description: "Phase 4: re-verify an existing person profile with targeted web searches and update it in place"
6858
7308
  }
6859
7309
  ]
6860
7310
  };