agentleFS
emtcmcaemtcmca/claude-for-legal-billing/skills/time-entry/SKILL.md

time-entry

Skill1 starsChanged 3 months agoMITView on GitHub

Add a time entry manually — for work done outside a Claude Code session, corrections, or entries not captured by the billing panel. Use when logging time for a phone call, document review done in another tool, court appearance, or any billable work not associated with a Claude session.

The file

Show its rules and text

We split this skill into the rules it gives an agent

19 rules. About 0 are common, 6 are distinctive, and 13 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈6

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 13

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read ~/.claude/plugins/config/claude-for-legal/billing/CLAUDE.md.

    line 26
  2. Very specific:

    Check if any argument or context identifies the attorney.

    line 32
  3. Very specific:

    Ask in sequence. Pre-fill from $ARGUMENTS if provided.

    line 36
  4. Very specific:

    If --client <slug> was passed and the client exists in [billing_data_path]/clients/, use it.

    line 39
  5. Very specific:

    If the client doesn't exist yet, ask: "Client [name] isn't in the system yet.

    line 41
  6. Very specific:

    If --matter <slug> was passed, use it.

    line 44
  7. Very specific:

    Ask: "How much time? (Enter as decimal hours like 0.8, or as minutes like 48m)"

    line 52
  8. Very specific:

    When the attorney entered minutes, record that raw figure in session_minutes_actual.

    line 55
  9. Distinctive:

    Look up the rate in order: client-specific override (from attorney YAML) → default rate (from attorney YAML).

    line 60
  10. Very specific:

    If billing arrangement is flat-fee or no-charge, show that instead of a rate prompt.

    line 62
  11. Distinctive:

    Ask: "Describe the work — this will appear on the invoice."

    line 65
  12. Very specific:

    If Task codes: required: ask "Task code (required):" — provide a quick reference:

    line 69
  13. Very specific:

    If Task codes: optional: ask with "(press enter to skip)"

    line 83
  14. Distinctive:

    Ask: "Activity code? (press enter to skip)" — provide a quick reference:

    line 90
  15. Very specific:

    Write the answer to activity_code.

    line 102
  16. Distinctive:

    Ask: "Any notes on this entry?

    line 106
  17. Very specific:

    Before writing, read time-register.yaml.

    line 110
  18. Distinctive:

    If any such entry is found, warn:

    line 119
  19. Distinctive:

    When a client doesn't exist and the attorney confirms creating one:

    line 173

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

/billing-legal:time-entry

When this runs

Attorney needs to log a time entry manually, outside of the end-of-session billing panel.

Instructions

Preflight - read /billing-legal:billing-guardrails first. It carries the approval gate, the append-only record rule, UTBMS field discipline, and the boundary on what this plugin records rather than decides. Where it conflicts with the steps below, the stricter rule wins.

1. Read config

Read ~/.claude/plugins/config/claude-for-legal/billing/CLAUDE.md. If [PLACEHOLDER] values are present, stop and direct to /billing-legal:cold-start-interview.

Get billing_data_path from config.

2. Determine which attorney

Check if any argument or context identifies the attorney. If not, read the attorney profiles in [billing_data_path]/attorneys/ and ask: "Which attorney is this entry for?" (If only one attorney is configured, use them without asking.)

3. Collect entry details

Ask in sequence. Pre-fill from $ARGUMENTS if provided.

Client:

  • If --client <slug> was passed and the client exists in [billing_data_path]/clients/, use it.
  • Otherwise, list available clients (from clients/*.yaml) and ask which one.
  • If the client doesn't exist yet, ask: "Client [name] isn't in the system yet. Create a profile now? [Y/n]". If yes, run a brief client intake (see "Creating a new client" below).

Matter:

  • If --matter <slug> was passed, use it.
  • Otherwise, ask: "What's the matter slug? (Leave blank if this entry isn't tied to a specific matter.)"

Date:

  • If --date YYYY-MM-DD was passed, use it.
  • Otherwise, default to today and confirm: "Date: [today] — correct? [Y/n]"

Hours:

  • Ask: "How much time? (Enter as decimal hours like 0.8, or as minutes like 48m)"
  • Convert minutes to hours: minutes / 60, then round UP to the next billing increment (from attorney's billing_increment setting, default 0.1h).
  • Show the result: "That's [raw] — rounded to [rounded]h at [increment]-hour increments. Use [rounded]h? [Y/n]"
  • When the attorney entered minutes, record that raw figure in session_minutes_actual. It is the only record of the gap between time worked and time billed, and it is what defends the round-up if a client's e-billing auditor asks. Leave it null only when they gave decimal hours directly.

Rate:

  • Look up the rate in order: client-specific override (from attorney YAML) → default rate (from attorney YAML).
  • Show: "Rate: $[rate]/hr — is that right? [Y/n]"
  • If billing arrangement is flat-fee or no-charge, show that instead of a rate prompt.

Narrative (required):

  • Ask: "Describe the work — this will appear on the invoice."
  • If the attorney submits a one-word or very short narrative (under 20 characters), gently push back: "Billing narratives should be descriptive enough for a client to understand what they're paying for. Can you add more detail? (e.g., 'Reviewed vendor NDA; drafted markup on confidentiality and IP ownership provisions.')"

Task code (optional or required, per config):

  • If Task codes: required: ask "Task code (required):" — provide a quick reference:
    • L100 Case Assessment / Strategy
    • L110 Fact Investigation / Development
    • L120 Analysis / Strategy
    • L160 Settlement / Non-Binding ADR
    • L190 Other Case Assessment
    • L200 Pre-Trial Pleadings and Motions
    • L210 Complaint
    • L250 Other Written Motions / Submissions
    • L300 Discovery
    • L310 Written Discovery
    • L320 Document Production
    • L400 Trial Preparation and Trial
    • L500 Appeal
  • If Task codes: optional: ask with "(press enter to skip)"
  • If Task codes: hidden: skip

Task codes are the UTBMS L-series. Activity codes are the A-series and are a separate field — do not offer A-codes here. They go to activity_code below.

Activity code (optional):

  • Ask: "Activity code? (press enter to skip)" — provide a quick reference:
    • A101 Plan and prepare for
    • A102 Research
    • A103 Draft / revise
    • A104 Review / analyze
    • A105 Communicate (in firm)
    • A106 Communicate (with client)
    • A107 Communicate (other outside counsel)
    • A108 Communicate (other external)
    • A109 Appear for / attend
    • A110 Manage data / files
    • A111 Other
  • Write the answer to activity_code. It exports in LINE_ITEM_ACTIVITY_CODE.
  • Skip this prompt entirely when Task codes: hidden.

Notes:

  • Ask: "Any notes on this entry? (Internal use only — won't appear on invoice. Press enter to skip.)"

4. Anti-double-billing check

Before writing, read time-register.yaml. If the file is empty or contains only comment lines (starting with #), treat it as an empty list.

If time-register.yaml does not exist, STOP. Say: "No time register at [billing_data_path]/time-register.yaml. That file is absent, not empty -- billing data may be unsynced, the data path may be wrong, or the file may have been moved. I am not going to report figures I cannot read." Do not create it, do not proceed with zeroes, and do not answer from earlier in the conversation. Absent is a different condition from empty or comment-only, which is the normal state of a fresh install.

Scan for entries with all three of:

  • Same attorney
  • Same client and matter_slug
  • Same date

If any such entry is found, warn:

There is already a time entry for [attorney] on [client] / [matter] for [date]: "[existing narrative]" ([existing hours]h). Are you sure you want to add another entry? Verify this is not a duplicate before proceeding — double-billing is a professional ethics violation. [Y/n]

Note: the check is date-level only because entries do not store start or end times. If the attorney confirms, proceed — they may legitimately have multiple entries on the same date (e.g., a morning review session and an afternoon call).

5. Confirm and write

Show the entry summary:

Ready to log:
  Date:       [date]
  Attorney:   [name]
  Client:     [client name]
  Matter:     [matter slug or "not specified"]
  Hours:      [hours]h   →   $[amount] at $[rate]/hr
  Task code:  [code or "—"]
  Narrative:  [narrative]
  Notes:      [notes or "—"]
  Status:     pending

Log this entry? [Y/n]

On confirmation, generate an entry ID (te-YYYY-MMDD-NNN where NNN is zero-padded sequential for the day) and append a new top-level list item to [billing_data_path]/time-register.yaml. If the file is empty or comment-only, the first entry becomes the first list item. Each item starts with - id: at column 0:

- id: te-[YYYY-MMDD]-[NNN]
  date: [YYYY-MM-DD]
  attorney: [slug]
  client: [slug]
  matter_slug: [slug or null]
  plugin: null
  hours: [hours]
  rate: [rate]
  amount: [hours * rate, rounded to 2 decimal places]
  original_hours: null
  original_amount: null
  task_code: [code or null]
  activity_code: [UTBMS activity code or null]
  narrative: "[narrative]"
  status: pending
  invoice_id: null
  session_minutes_actual: [raw minutes the attorney entered, or null if they gave decimal hours]
  ai_cost_usd: null
  notes: "[notes or null]"
  activity_log: null

After writing, confirm:

✓ Logged: [hours]h for [client name] on [date] — status: pending (ID: [id])

Creating a new client

When a client doesn't exist and the attorney confirms creating one:

Ask:

  1. Client display name (how it appears on invoices)
  2. Slug (suggest from name, confirm)
  3. Billing contact (name + email; e.g., "Jane Smith <jane@client.com>")
  4. Billing address
  5. Billing arrangement (hourly | flat-fee | contingency | no-charge | courtesy) — default hourly
  6. Budget cap (press enter for none)
  7. Retainer balance (press enter for none)
  8. Notes (e.g., "Prefers monthly invoices")

Write to [billing_data_path]/clients/[slug].yaml:

slug: [slug]
name: [display name]
billing_contact: "[name] <[email]>"
billing_address: "[address]"
arrangement: [arrangement]
budget_cap: [number or null]
budget_billed: 0
retainer_balance: [number or null]
notes: "[notes or null]"

What this skill does not do

  • Generate invoices — use /billing-legal:invoice-generate
  • Review pending entries — use /billing-legal:wip-review
  • Set hourly rates — use /billing-legal:rate-card

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.